Merge branch 'develop'

This commit is contained in:
caoqianming 2024-05-29 10:41:32 +08:00
commit 9bc6985ff8
101 changed files with 4156 additions and 2700 deletions

View File

@ -2,6 +2,7 @@
ENV = 'production' ENV = 'production'
# base api # base api
#VUE_APP_BASE_API = 'http://192.168.1.250/api'
VUE_APP_BASE_API = 'http://49.232.14.174:2222/api' VUE_APP_BASE_API = 'http://49.232.14.174:2222/api'
#VUE_APP_BASE_API = 'http://127.0.0.1:8000/api' #VUE_APP_BASE_API = 'http://127.0.0.1:8000/api'

View File

@ -29,7 +29,11 @@
"element-ui": "^2.15.5", "element-ui": "^2.15.5",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"fuse.js": "^6.4.6", "fuse.js": "^6.4.6",
"html-docx-js": "^0.3.1",
"html-docx-js-typescript": "^0.1.5",
"html2canvas": "^1.4.1",
"js-cookie": "^3.0.0", "js-cookie": "^3.0.0",
"jspdf": "^2.5.1",
"mammoth": "^1.4.19", "mammoth": "^1.4.19",
"normalize.css": "^8.0.1", "normalize.css": "^8.0.1",
"nprogress": "0.2.0", "nprogress": "0.2.0",

View File

@ -65,6 +65,13 @@ export function getTestRecord(query) {
params: query params: query
}) })
} }
//检测记录模板
export function getTestRecordExport(id) {
return request({
url: `/qm/testrecord/${id}/export/`,
method: 'get'
})
}
//检测记录 //检测记录
export function getTestRecordItem(id) { export function getTestRecordItem(id) {
return request({ return request({

View File

@ -8,6 +8,14 @@ export function login(data) {
}) })
} }
export function refreshToken(data) {
return request({
url: '/auth/token/refresh/',
method: 'post',
data
})
}
export function logout() { export function logout() {
return request({ return request({
url: '/auth/token/black/', url: '/auth/token/black/',

View File

@ -3,7 +3,7 @@
<el-form <el-form
id="customerForm" id="customerForm"
ref="checkForm" ref="checkForm"
label-width="100px" label-width="150px"
:model="checkForm" :model="checkForm"
> >
<el-row> <el-row>
@ -32,8 +32,8 @@
required required
> >
<el-input-number <el-input-number
style="width: 100%;"
v-model="checkForm[item.field_key]" v-model="checkForm[item.field_key]"
style="width: 100%;"
step-strictly step-strictly
placeholder="请输入" placeholder="请输入"
:min="0" :min="0"
@ -46,8 +46,8 @@
required required
> >
<el-input-number <el-input-number
style="width: 100%;"
v-model="checkForm[item.field_key]" v-model="checkForm[item.field_key]"
style="width: 100%;"
:precision="2" :precision="2"
:step="0.1" :step="0.1"
placeholder="请输入" placeholder="请输入"
@ -133,7 +133,7 @@
<el-row v-show="hasPicture"> <el-row v-show="hasPicture">
<el-form-item label="图表"> <el-form-item label="图表">
<div> <div>
<img id="canvasImg" :src="img" style="width:500px;height: 300px;display: none"> <img id="canvasImg" :src="img" alt="tupian">
<div style="position: relative;display: flex;flex-direction: column; <div style="position: relative;display: flex;flex-direction: column;
border: 1px solid #DCDFE6;"> border: 1px solid #DCDFE6;">
<canvas id="canvas" width="500" height="300"> <canvas id="canvas" width="500" height="300">
@ -158,6 +158,16 @@
<el-radio v-model="is_testok" :label="testokTrue">检查合格</el-radio> <el-radio v-model="is_testok" :label="testokTrue">检查合格</el-radio>
<el-radio v-model="is_testok" :label="testokFalse">检查不合格</el-radio> <el-radio v-model="is_testok" :label="testokFalse">检查不合格</el-radio>
</el-form-item> </el-form-item>
<el-col :span="12">
<el-form-item label="编号">
<el-input v-model="numbers" @input="checkValue" placeholder="编号"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注">
<el-input v-model="remark" placeholder="备注"/>
</el-form-item>
</el-col>
<div class="dialog-footer" style="text-align: right" v-show="!isDisabled"> <div class="dialog-footer" style="text-align: right" v-show="!isDisabled">
<el-button @click="recordCancel"> </el-button> <el-button @click="recordCancel"> </el-button>
<el-button type="primary" @click="submitfield('1')">保存</el-button> <el-button type="primary" @click="submitfield('1')">保存</el-button>
@ -170,6 +180,7 @@
<script> <script>
import {upFile} from "@/api/file"; import {upFile} from "@/api/file";
let preDrawAry = []; let preDrawAry = [];
export default { export default {
name: "index", name: "index",
@ -178,7 +189,8 @@
type: Array, type: Array,
default: () => { default: () => {
return [] return []
}} , }
},
formID: { formID: {
type: Number, type: Number,
default: 0 default: 0
@ -198,7 +210,15 @@
isDisabled: { isDisabled: {
type: Boolean, type: Boolean,
default: false default: false
} },
numbers: {
type: String,
default: ''
},
remark:{
type: String,
default: ''
},
}, },
mounted() { mounted() {
let that = this; let that = this;
@ -227,7 +247,7 @@
that.is_save = true; that.is_save = true;
} else { } else {
that.checkForm[key] = ''; that.checkForm[key] = '';
that.$set(that.checkForm,key,null) that.$set(that.checkForm, key, '')
} }
} }
let listJudge = this.formData.filter(item => { let listJudge = this.formData.filter(item => {
@ -244,11 +264,11 @@
if (imag.length > 0) { if (imag.length > 0) {
that.img = new Image(); that.img = new Image();
that.img.crossOrigin = 'anonymous'; that.img.crossOrigin = 'anonymous';
let value = imag[0].field_value?imag[0].field_value:imag[0].draw_template; let value = imag[0].field_value!==null&&imag[0].field_value!==undefined&&imag[0].field_value!=='' ? imag[0].field_value : imag[0].draw_template;
that.img = 'http://49.232.14.174:2222'+value; that.img =process.env.VUE_APP_BASE_API.replace('/api','')+ value;
setTimeout(function () { setTimeout(function () {
that.canvasInit(); that.canvasInit();
},500); }, 1000);
} }
}, },
data() { data() {
@ -282,9 +302,13 @@
is_save: false, is_save: false,
require: false, require: false,
testokFalse: false, testokFalse: false,
index: '1',
} }
}, },
methods: { methods: {
checkValue() {
this.numbers = this.numbers.replace(/[^0-9a-zA-Z]/g, '');
},
filterBlock(rule, index, field_key) { filterBlock(rule, index, field_key) {
let that = this; let that = this;
if (rule !== '' && rule !== null && rule !== undefined) { if (rule !== '' && rule !== null && rule !== undefined) {
@ -334,7 +358,7 @@
that.formData[index].is_hidden = false; that.formData[index].is_hidden = false;
} else { } else {
that.formData[index].is_hidden = true; that.formData[index].is_hidden = true;
that.checkForm[field_key] = null; that.checkForm[field_key] = '';
} }
return rea; return rea;
} else { } else {
@ -347,7 +371,7 @@
that.formData[index].is_hidden = false; that.formData[index].is_hidden = false;
} else { } else {
that.formData[index].is_hidden = true; that.formData[index].is_hidden = true;
that.checkForm[field_key] = null; that.checkForm[field_key] = '';
} }
return eval(eval(a)); return eval(eval(a));
} }
@ -433,10 +457,9 @@
}, },
//画布添加背景模板图 //画布添加背景模板图
draw() { draw() {
this.ctx = document.getElementById('canvas').getContext('2d');
let canvasImg = document.getElementById("canvasImg"); let canvasImg = document.getElementById("canvasImg");
canvasImg.setAttribute("crossOrigin",'anonymous'); // canvasImg.setAttribute("crossOrigin", 'anonymous');
canvasImg.style.width = '500px';
canvasImg.style.height = '300px';
this.ctx.drawImage(canvasImg, 0, 0, 500, 300); this.ctx.drawImage(canvasImg, 0, 0, 500, 300);
}, },
// 叉号 // 叉号
@ -669,6 +692,7 @@
//提交检查项目 //提交检查项目
submitfield(isSubmit) { submitfield(isSubmit) {
let that = this; let that = this;
that.index = isSubmit;
let drawArr = that.formData.filter(item => { let drawArr = that.formData.filter(item => {
return item.field_type === 'draw'; return item.field_type === 'draw';
}); });
@ -687,17 +711,17 @@
let key = drawArr[0].field_key; let key = drawArr[0].field_key;
that.imgUrl = res.data.path; that.imgUrl = res.data.path;
that.checkForm[key] = res.data.path; that.checkForm[key] = res.data.path;
that.fieldData(isSubmit); that.fieldData();
} }
}); });
} else { } else {
that.fieldData(isSubmit); that.fieldData();
} }
}, },
fieldData(isSubmit){ fieldData() {
debugger;
let that = this; let that = this;
that.field = []; //检查项目 that.field = []; //检查项目
let submit = isSubmit=='1'?false:true;
that.formData.forEach((item) => { that.formData.forEach((item) => {
let field_value; let field_value;
if (item.field_type === 'int') { if (item.field_type === 'int') {
@ -717,7 +741,9 @@
that.testrecord.record_data = that.field;//检查项列表 that.testrecord.record_data = that.field;//检查项列表
that.testrecord.is_testok = that.is_testok;//检查表检查结果 that.testrecord.is_testok = that.is_testok;//检查表检查结果
that.testrecord.id = that.recordId;//记录id that.testrecord.id = that.recordId;//记录id
if(submit){//提交 that.testrecord.number = that.numbers;//编号
that.testrecord.remark = that.remark;//备注
if (that.index === '2') {//提交
this.$emit('recordSubmit', that.testrecord); this.$emit('recordSubmit', that.testrecord);
} else {//保存 } else {//保存
this.$emit('recordSave', that.testrecord); this.$emit('recordSave', that.testrecord);
@ -756,6 +782,7 @@
margin-right: 10px; margin-right: 10px;
margin-bottom: 10px; margin-bottom: 10px;
} }
.hide { .hide {
display: none; display: none;
} }
@ -794,11 +821,13 @@
#res { #res {
display: inline-block; display: inline-block;
} }
.helpText { .helpText {
position: absolute; position: absolute;
top: 40px; top: 40px;
left: 100px; left: 100px;
} }
.adoptTip { .adoptTip {
position: absolute; position: absolute;
top: 38px; top: 38px;
@ -806,6 +835,7 @@
font-size: 12px; font-size: 12px;
color: #46ce7a; color: #46ce7a;
} }
.failTip { .failTip {
position: absolute; position: absolute;
top: 38px; top: 38px;
@ -813,4 +843,11 @@
font-size: 12px; font-size: 12px;
color: #ff0000; color: #ff0000;
} }
#canvasImg{
width:500px;
height: 300px;
position: absolute;
left: 50%;
transform: translateX(-50%)
}
</style> </style>

View File

@ -3,7 +3,7 @@
<el-form <el-form
id="customerForm" id="customerForm"
ref="checkForm" ref="checkForm"
label-width="100px" label-width="150px"
:model="checkForm" :model="checkForm"
> >
<el-row> <el-row>
@ -217,10 +217,10 @@
<img :src="originImg"> <img :src="originImg">
</div> </div>
<div class="halfWidth"> <div class="halfWidth">
<img id="canvasImg" src="./../../assets/glass.png" style="width:500px;height: 300px;display: none"> <img id="canvasImg" :src="img" style="width:450px;height: 300px;display: none">
<div style="position: relative;display: flex;flex-direction: column; <div style="position: relative;display: flex;flex-direction: column;
border: 1px solid #DCDFE6;"> border: 1px solid #DCDFE6;">
<canvas id="canvas" width="500" height="300"> <canvas id="canvas" width="450" height="300">
您的浏览器不支持绘图请升级或更换浏览器 您的浏览器不支持绘图请升级或更换浏览器
</canvas> </canvas>
<input type="text" value="" class="hide" id="txt" placeholder="请输入文字"> <input type="text" value="" class="hide" id="txt" placeholder="请输入文字">
@ -329,8 +329,8 @@
}); });
that.img = new Image(); that.img = new Image();
that.img.crossOrigin = ''; that.img.crossOrigin = '';
that.img = 'http://49.232.14.174:2222'+imag[0].field_value; that.img = process.env.VUE_APP_BASE_API.replace('/api','')+imag[0].field_value;
that.originImg = 'http://49.232.14.174:2222'+imag[0].origin_value; that.originImg = process.env.VUE_APP_BASE_API.replace('/api','')+ imag[0].origin_value;
listJudge.forEach(item => { listJudge.forEach(item => {
let obj = new Object(); let obj = new Object();
obj = item; obj = item;
@ -374,6 +374,7 @@
is_testok:true, is_testok:true,
testokTrue:true, testokTrue:true,
testokFalse:false, testokFalse:false,
index:'1',
} }
}, },
methods:{ methods:{
@ -382,7 +383,7 @@
let that = this; let that = this;
if(rule!==''&&rule!==null&&rule!==undefined){ if(rule!==''&&rule!==null&&rule!==undefined){
let reg = /\{(.+?)\}/g; let reg = /\{(.+?)\}/g;
debugger; // debugger;
if(rule.indexOf('||')>-1||rule.indexOf('&&')>-1){ if(rule.indexOf('||')>-1||rule.indexOf('&&')>-1){
let tam = '', arr = []; let tam = '', arr = [];
if(rule.indexOf('||')>-1){ if(rule.indexOf('||')>-1){
@ -428,7 +429,7 @@
that.formData[index].is_hidden = false; that.formData[index].is_hidden = false;
}else{ }else{
that.formData[index].is_hidden = true; that.formData[index].is_hidden = true;
that.checkForm[field_key] = null; that.checkForm[field_key] = '';
} }
return rea; return rea;
}else{ }else{
@ -441,7 +442,7 @@
that.formData[index].is_hidden = false; that.formData[index].is_hidden = false;
}else{ }else{
that.formData[index].is_hidden = true; that.formData[index].is_hidden = true;
that.checkForm[field_key] = null; that.checkForm[field_key] = '';
} }
return eval(eval(a)); return eval(eval(a));
} }
@ -765,6 +766,7 @@
//提交检查项目 //提交检查项目
submitfield(isSubmit) { submitfield(isSubmit) {
let that = this; let that = this;
that.index = isSubmit;
let drawArr = that.formData.filter(item=>{ let drawArr = that.formData.filter(item=>{
return item.field_type==='draw'; return item.field_type==='draw';
}); });
@ -787,14 +789,12 @@
} }
}); });
}else{ }else{
that.fieldData(isSubmit); that.fieldData();
} }
}, },
fieldData(isSubmit){ fieldData(){
let that = this; let that = this;
that.field = []; //检查项目 that.field = []; //检查项目
// debugger;
let submit = isSubmit=='1'?false:true;
that.formData.forEach((item) => { that.formData.forEach((item) => {
let field_value = null; let field_value = null;
if(item.field_type==='int'){ if(item.field_type==='int'){
@ -816,7 +816,7 @@
that.testrecord.id = that.recordId; that.testrecord.id = that.recordId;
// debugger; // debugger;
// if(submit&&that.isMidTesting!==true){//提交 // if(submit&&that.isMidTesting!==true){//提交
if(submit){//提交 if(that.index==='2'){//提交
this.$emit('recordSubmit',that.testrecord); this.$emit('recordSubmit',that.testrecord);
}else {//保存 }else {//保存
this.$emit('recordSave',that.testrecord); this.$emit('recordSave',that.testrecord);

View File

@ -128,7 +128,8 @@
ctx.drawImage(video, 0, 0, canvas.width, canvas.height); ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
let base64Img = canvas.toDataURL('image/jpeg'); let base64Img = canvas.toDataURL('image/jpeg');
let img = base64Img.split(',')[1]; let img = base64Img.split(',')[1];
let imgData = {base64:img}; // let imgData = {base64:img};
let imgData = {base64: img,tolerance:0.43};
faceLogin(imgData).then((res) => { faceLogin(imgData).then((res) => {
if (res.code >= 200) { if (res.code >= 200) {
const isEdit = that.dialogType === "edit"; const isEdit = that.dialogType === "edit";

View File

@ -2,10 +2,10 @@
<div class="faceLoginWrap"> <div class="faceLoginWrap">
<div style="height: 500px;"> <div style="height: 500px;">
<div class="video-box"> <div class="video-box">
<video id="video" width="500" height="500" preload autoplay loop muted></video> <video id="video" width="600" preload autoplay loop muted></video>
<canvas id="canvas" width="500" height="500"></canvas> <canvas id="canvas" width="600" height="500"></canvas>
</div> </div>
<canvas id="screenshotCanvas" width="500" height="500"></canvas> <canvas id="screenshotCanvas" width="600" height="500"></canvas>
</div> </div>
</div> </div>
</template> </template>
@ -132,7 +132,7 @@
if(res.data.access){ if(res.data.access){
let item= {name:res.data.name,token:res.data.access}; let item= {name:res.data.name,token:res.data.access};
that.$emit('func',item); that.$emit('func',item);
that.$message.success("身份认证成功!"); // that.$message.success("身份认证成功!");
this.closeCamera(); this.closeCamera();
}else{ }else{
that.uploadLock = false; that.uploadLock = false;
@ -165,7 +165,6 @@
beforeDestroy() { beforeDestroy() {
let video = document.getElementById('video'); let video = document.getElementById('video');
let stream = video.srcObject; let stream = video.srcObject;
// console.log(stream);
let tracks = stream.getTracks(); let tracks = stream.getTracks();
tracks.forEach(track => { tracks.forEach(track => {
track.stop() track.stop()
@ -188,8 +187,7 @@
.video-box { .video-box {
margin: auto; margin: auto;
position: relative; position: relative;
width: 500px; width: 600px;
height: 500px;
text-align: center; text-align: center;
} }

View File

@ -1,11 +1,11 @@
<template> <template>
<div class="faceLoginWrap"> <div class="faceLoginWrap">
<div style="height: 500px;"> <div style="height:fit-content;">
<div class="video-box"> <div class="video-box">
<video id="video" width="500" height="500" preload autoplay loop muted></video> <video id="video" width="600" preload autoplay muted></video>
<canvas id="canvas" width="500" height="500"></canvas> <canvas id="canvas" width="600" height="500"></canvas>
</div> </div>
<canvas id="screenshotCanvas" width="500" height="500"></canvas> <canvas id="screenshotCanvas" width="600" height="500"></canvas>
</div> </div>
</div> </div>
</template> </template>
@ -118,22 +118,28 @@
ctx.drawImage(video, 0, 0, canvas.width, canvas.height); ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
let base64Img = canvas.toDataURL('image/jpeg'); let base64Img = canvas.toDataURL('image/jpeg');
let img = base64Img.split(',')[1]; let img = base64Img.split(',')[1];
let imgData = {base64: img}; let tolerance = parseFloat(localStorage.getItem('tolerance'));
let imgData = {base64: img,tolerance};
clockRecord(imgData).then((res) => { clockRecord(imgData).then((res) => {
debugger;
if (res.code === 200 && res.data.id) { if (res.code === 200 && res.data.id) {
this.$message.success(res.data.name + '签到成功!'); // this.$message.success(res.data.name + '签到成功!');
let messag = '<div style="font-size:30px"><strong> <i style="font-size:40px">'+res.data.name+'</i> 签到成功</strong></div>';
this.$message.success({
dangerouslyUseHTMLString: true,
duration:4000,
message: messag
});
setTimeout(() => { setTimeout(() => {
that.uploadLock = false; that.uploadLock = false;
}, 3000) }, 5000)
} else { } else {
// 打开锁
that.uploadLock = false; that.uploadLock = false;
this.$message.error(res.msg);
} }
}).catch(() => { }).catch(() => {
// 打开锁 // 打开锁
that.uploadLock = false; that.uploadLock = false;
// this.$message.error('面部识别失败请重新验证');
}); });
}, },
closeCamera() { closeCamera() {
@ -143,6 +149,9 @@
} }
</script> </script>
<style scoped> <style scoped>
.el-message .el-icon-success{
font-size: 35px!important;
}
.faceLoginWrap{ .faceLoginWrap{
/*padding: 50px;*/ /*padding: 50px;*/
/*width: 600px;*/ /*width: 600px;*/
@ -157,8 +166,8 @@
} }
.video-box { .video-box {
width: 500px; width: 600px;
height: 500px; height: fit-content;
margin: auto; margin: auto;
position: relative; position: relative;
} }
@ -176,4 +185,3 @@
left: 0; left: 0;
} }
</style> </style>

View File

@ -25,7 +25,7 @@
import { Navbar, Sidebar, AppMain,TagsView } from './components' import { Navbar, Sidebar, AppMain,TagsView } from './components'
import ResizeMixin from './mixin/ResizeHandler' import ResizeMixin from './mixin/ResizeHandler'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import { getToken } from '@/utils/auth' // get token from cookie import { getToken,getRefresh } from '@/utils/auth' // get token from cookie
export default { export default {
name: 'Layout', name: 'Layout',
components: { components: {
@ -64,12 +64,12 @@ export default {
}, },
mounted() { mounted() {
let hasToken = getToken(); let hasToken = getToken();
/*debugger;
console.log(hasToken);*/
if (hasToken) { if (hasToken) {
this.refreshCountData();
this.$store.dispatch("user/getCount", {}); this.$store.dispatch("user/getCount", {});
}else{
this.$router.push({name:'login'})
} }
// this.refreshCountData();
}, },
methods: { methods: {
refreshCountData(){ refreshCountData(){
@ -80,12 +80,11 @@ export default {
this.$store.dispatch("user/getCount", {}); this.$store.dispatch("user/getCount", {});
} }
},0) },0)
},5000) },50000)
}, },
handleClickOutside() { handleClickOutside() {
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false }) this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
}, },
gotoTicketPage(){ gotoTicketPage(){
let path = this.$route.path; let path = this.$route.path;
if(path==='/workflow/ticket'){ if(path==='/workflow/ticket'){

View File

@ -113,7 +113,7 @@ export const asyncRoutes = [
path: 'material/:id', path: 'material/:id',
name: 'MaterialDO', name: 'MaterialDO',
component: () => import('@/views/mtm/materialdo.vue'), component: () => import('@/views/mtm/materialdo.vue'),
meta: { title: '绑定检查表', perms: ['vendor_manage'] }, meta: { title: '绑定检查表' },
hidden: true hidden: true
} }
, ,
@ -121,8 +121,21 @@ export const asyncRoutes = [
path: 'materialDetail/:id', path: 'materialDetail/:id',
name: 'MaterialDetail', name: 'MaterialDetail',
component: () => import('@/views/mtm/materialDetail.vue'), component: () => import('@/views/mtm/materialDetail.vue'),
meta: { title: '物料详情', perms: ['vendor_manage'] }, meta: { title: '物料详情' },
hidden: true hidden: true
}
,{
path: 'wproductList',
name: 'wproductList',
component: () => import('@/views/mtm/wproductList'),
meta: { title: '半成品列表', icon: 'material', perms: ['mtm_wproduct'] }
},
{
path: 'productList',
name: 'productList',
component: () => import('@/views/mtm/productList'),
meta: { title: '成品列表', icon: 'material', perms: ['mtm_product'] }
}, },
{ {
path: 'process', path: 'process',
@ -134,7 +147,7 @@ export const asyncRoutes = [
path: 'step/:id', path: 'step/:id',
name: 'Step', name: 'Step',
component: () => import('@/views/mtm/step.vue'), component: () => import('@/views/mtm/step.vue'),
meta: { title: '子工序', perms: ['vendor_manage'] }, meta: { title: '子工序'},
hidden: true hidden: true
} }
, ,
@ -142,7 +155,7 @@ export const asyncRoutes = [
path: 'stepdo/:id', path: 'stepdo/:id',
name: 'StepDo', name: 'StepDo',
component: () => import('@/views/mtm/stepdo.vue'), component: () => import('@/views/mtm/stepdo.vue'),
meta: { title: '子工序查看', perms: ['vendor_manage'] }, meta: { title: '子工序查看'},
hidden: true hidden: true
}, },
{ {
@ -151,18 +164,7 @@ export const asyncRoutes = [
component: () => import('@/views/mtm/productprocess'), component: () => import('@/views/mtm/productprocess'),
meta: { title: '产品管理', icon: 'product', perms: ['mtm_productprocess'] } meta: { title: '产品管理', icon: 'product', perms: ['mtm_productprocess'] }
} }
,{
path: 'productList',
name: 'productList',
component: () => import('@/views/mtm/productList'),
meta: { title: '成品列表', icon: 'material', perms: ['mtm_material'] }
}
,{
path: 'wproductList',
name: 'wproductList',
component: () => import('@/views/mtm/wproductList'),
meta: { title: '半成品列表', icon: 'material', perms: ['mtm_material'] }
}
] ]
}, },
{ {
@ -183,7 +185,7 @@ export const asyncRoutes = [
path: 'work/:id', path: 'work/:id',
name: 'work', name: 'work',
component: () => import('@/views/pm/work'), component: () => import('@/views/pm/work'),
meta: { title: '生产子计划', perms: ['pm_plan'] }, meta: { title: '生产子计划'},
hidden: true hidden: true
}, },
{ {
@ -204,7 +206,7 @@ export const asyncRoutes = [
path: 'plandetails/:id', path: 'plandetails/:id',
name: 'plandetails', name: 'plandetails',
component: () => import('@/views/pm/plandetails'), component: () => import('@/views/pm/plandetails'),
meta: { title: '生产任务详情', perms: ['pm_testitem'] }, meta: { title: '生产任务详情'},
hidden: true hidden: true
} }
, ,
@ -213,7 +215,7 @@ export const asyncRoutes = [
path: 'processcard/:id', path: 'processcard/:id',
name: 'processcard', name: 'processcard',
component: () => import('@/views/pm/processcard'), component: () => import('@/views/pm/processcard'),
meta: { title: '流程卡', perms: ['vendor_manage'] }, meta: { title: '流程卡' },
hidden: true hidden: true
} }
@ -261,9 +263,8 @@ export const asyncRoutes = [
path: 'firstCheck', path: 'firstCheck',
name: 'firstCheck', name: 'firstCheck',
component: () => import('@/views/wpm/firstCheck'), component: () => import('@/views/wpm/firstCheck'),
meta: { title: '首件确认', icon: 'finishedCheck', perms: ['wpm_firstCheck'] ,noCache: true} meta: { title: '首件确认', icon: 'finishedCheck', perms: ['wpm_firstCheck']}
} }
] ]
}, },
{ {
@ -317,7 +318,7 @@ export const asyncRoutes = [
path: 'contractdetail/:id', path: 'contractdetail/:id',
name: 'contractdetail', name: 'contractdetail',
component: () => import('@/views/sam/contractdetail'), component: () => import('@/views/sam/contractdetail'),
meta: { title: '合同详情', perms: ['sam_contract'] }, meta: { title: '合同详情'},
hidden: true hidden: true
} }
@ -334,7 +335,7 @@ export const asyncRoutes = [
path: 'orderdetail/:id', path: 'orderdetail/:id',
name: 'orderdetail', name: 'orderdetail',
component: () => import('@/views/sam/orderdetail'), component: () => import('@/views/sam/orderdetail'),
meta: { title: '订单详情', perms: ['sam_order'] }, meta: { title: '订单详情'},
hidden: true hidden: true
}, },
{ {
@ -348,7 +349,7 @@ export const asyncRoutes = [
path: 'salesdetail/:id', path: 'salesdetail/:id',
name: 'salesdetail', name: 'salesdetail',
component: () => import('@/views/sam/salesdetail'), component: () => import('@/views/sam/salesdetail'),
meta: { title: '销售详情', perms: ['sam_sales'] }, meta: { title: '销售详情'},
hidden: true hidden: true
} }
] ]
@ -384,7 +385,7 @@ export const asyncRoutes = [
path: 'taskdetails/:id', path: 'taskdetails/:id',
name: 'taskdetails', name: 'taskdetails',
component: () => import('@/views/qm/taskdetails'), component: () => import('@/views/qm/taskdetails'),
meta: { title: '过程检验详情', perms: ['qm_processtest'] }, meta: { title: '过程检验详情'},
hidden: true hidden: true
} }
, ,
@ -392,7 +393,7 @@ export const asyncRoutes = [
path: 'wproduct/:id', path: 'wproduct/:id',
name: 'wproduct', name: 'wproduct',
component: () => import('@/views/qm/wproduct'), component: () => import('@/views/qm/wproduct'),
meta: { title: '工序玻璃', perms: ['vendor_manage'] }, meta: { title: '工序玻璃' },
hidden: true hidden: true
} }
, ,
@ -400,7 +401,7 @@ export const asyncRoutes = [
path: 'taskrecordfrom/:id', path: 'taskrecordfrom/:id',
name: 'taskrecordfrom', name: 'taskrecordfrom',
component: () => import('@/views/qm/taskrecordfrom'), component: () => import('@/views/qm/taskrecordfrom'),
meta: { title: '检验记录', perms: ['vendor_manage'] }, meta: { title: '检验记录'},
hidden: true hidden: true
} }
, ,
@ -424,19 +425,19 @@ export const asyncRoutes = [
component: Layout, component: Layout,
redirect: '/personnel/user', redirect: '/personnel/user',
name: 'personnel', name: 'personnel',
meta: { title: '人员管理', icon: 'user', perms: ['personnel_set'] }, meta: { title: '人员管理', icon: 'user', perms: ['employee_manage'] },
children: [ children: [
{ {
path: 'user', path: 'user',
name: 'user', name: 'user',
component: () => import('@/views/personnel/user'), component: () => import('@/views/personnel/user'),
meta: { title: '人员列表', icon: 'userList', perms: ['personnel_user'] } meta: { title: '人员列表', icon: 'userList', perms: ['employee_userList'] }
}, },
{ {
path: 'attendance', path: 'attendance',
name: 'attendance', name: 'attendance',
component: () => import('@/views/personnel/attendance'), component: () => import('@/views/personnel/attendance'),
meta: { title: '考勤列表', icon: 'attendance', perms: ['personnel_attendance'] } meta: { title: '考勤列表', icon: 'attendance', perms: ['employee_attendance'] }
} ,{ } ,{
path: 'userupdate/:id', path: 'userupdate/:id',
name: 'userupdate', name: 'userupdate',
@ -464,7 +465,7 @@ export const asyncRoutes = [
path: 'inventory/:id', path: 'inventory/:id',
name: 'inventory', name: 'inventory',
component: () => import('@/views/inm/inventory'), component: () => import('@/views/inm/inventory'),
meta: { title: '仓库物料', perms: ['vendor_manage'] }, meta: { title: '仓库物料' },
hidden: true hidden: true
} }
, ,
@ -484,7 +485,7 @@ export const asyncRoutes = [
path: 'fifodetail/:id', path: 'fifodetail/:id',
name: 'fifodetail', name: 'fifodetail',
component: () => import('@/views/inm/fifodetail'), component: () => import('@/views/inm/fifodetail'),
meta: { title: '仓库物料', perms: ['vendor_manage'] }, meta: { title: '仓库物料'},
hidden: true hidden: true
}, },
{ {
@ -507,25 +508,25 @@ export const asyncRoutes = [
component: Layout, component: Layout,
redirect: '/procurement/vendor', redirect: '/procurement/vendor',
name: 'procurement', name: 'procurement',
meta: { title: '采购管理', icon: 'purchase', perms: ['procurement_manage'] }, meta: { title: '采购管理', icon: 'purchase', perms: ['pum_manage'] },
children: [ children: [
{ {
path: 'vendor', path: 'vendor',
name: 'vendor', name: 'vendor',
component: () => import('@/views/procurement/vendor'), component: () => import('@/views/procurement/vendor'),
meta: { title: '供应商', icon: 'supplier', perms: ['procurement_vendor'] } meta: { title: '供应商', icon: 'supplier', perms: ['pum_vendor'] }
}, },
{ {
path: 'puorder', path: 'puorder',
name: 'puorder', name: 'puorder',
component: () => import('@/views/procurement/puorder'), component: () => import('@/views/procurement/puorder'),
meta: { title: '采购订单', icon: 'purchaseOrder', perms: ['procurement_puorder'] } meta: { title: '采购订单', icon: 'purchaseOrder', perms: ['pum_puorder'] }
}, },
{ {
path: 'puorderitem/:id', path: 'puorderitem/:id',
name: 'puorderitem', name: 'puorderitem',
component: () => import('@/views/procurement/puorderitem'), component: () => import('@/views/procurement/puorderitem'),
meta: { title: '采购订单项', perms: ['procurement_puorder'] }, meta: { title: '采购订单项'},
hidden: true hidden: true
} }
] ]
@ -555,7 +556,7 @@ export const asyncRoutes = [
component: () => import('@/views/statistics/personStatistics'), component: () => import('@/views/statistics/personStatistics'),
meta: { title: '人员统计', icon: 'personStatistics', perms: ['statistics_personStatistics'] } meta: { title: '人员统计', icon: 'personStatistics', perms: ['statistics_personStatistics'] }
}, },
{ /* {
path: 'costStatistics', path: 'costStatistics',
name: 'costStatistics', name: 'costStatistics',
component: () => import('@/views/statistics/costStatistics'), component: () => import('@/views/statistics/costStatistics'),
@ -566,7 +567,7 @@ export const asyncRoutes = [
name: 'testStatistics', name: 'testStatistics',
component: () => import('@/views/statistics/testStatistics'), component: () => import('@/views/statistics/testStatistics'),
meta: { title: '检验统计', icon: 'testStatistics', perms: ['workflow_index'] } meta: { title: '检验统计', icon: 'testStatistics', perms: ['workflow_index'] }
}, },*/
] ]
}, },
@ -677,7 +678,7 @@ export const asyncRoutes = [
path: 'file', path: 'file',
name: 'File', name: 'File',
component: () => import('@/views/system/file'), component: () => import('@/views/system/file'),
meta: { title: '文件库', icon: 'home', perms: ['file_room'] } meta: { title: '文件库', icon: 'home', perms: ['system_file'] }
}, },
{ {
path: 'task', path: 'task',

View File

@ -2,6 +2,7 @@ const getters = {
sidebar: state => state.app.sidebar, sidebar: state => state.app.sidebar,
device: state => state.app.device, device: state => state.app.device,
token: state => state.user.token, token: state => state.user.token,
refresh: state => state.user.refresh,
avatar: state => state.user.avatar, avatar: state => state.user.avatar,
name: state => state.user.name, name: state => state.user.name,
perms: state => state.user.perms, perms: state => state.user.perms,

View File

@ -1,5 +1,6 @@
import { login, logout, getInfo } from '@/api/user' import { login, logout, getInfo } from '@/api/user'
import { getCount } from '@/api/workflow' import { getCount } from '@/api/workflow'
import { refreshToken } from '@/api/user'
import { getToken, setToken, removeToken} from '@/utils/auth' import { getToken, setToken, removeToken} from '@/utils/auth'
import { resetRouter } from '@/router' import { resetRouter } from '@/router'
@ -7,6 +8,7 @@ const getDefaultState = () => {
return { return {
token: getToken(), token: getToken(),
name: '', name: '',
refresh: '',
avatar: '', avatar: '',
count: {}, count: {},
perms: [] perms: []
@ -22,6 +24,9 @@ const mutations = {
SET_TOKEN: (state, token) => { SET_TOKEN: (state, token) => {
state.token = token state.token = token
}, },
SET_REFRESH: (state, refresh) => {
state.refresh = refresh
},
SET_NAME: (state, name) => { SET_NAME: (state, name) => {
state.name = name state.name = name
}, },
@ -44,9 +49,10 @@ const actions = {
login({ username: username.trim(), password: password }).then(response => { login({ username: username.trim(), password: password }).then(response => {
const { data } = response; const { data } = response;
commit('SET_TOKEN', data.access); commit('SET_TOKEN', data.access);
commit('SET_REFRESH', data.refresh);
sessionStorage.setItem('refresh',data.refresh);
setToken(data.access); setToken(data.access);
resolve() resolve()
}).catch(error => { }).catch(error => {
reject(error) reject(error)
}) })
@ -63,14 +69,11 @@ const actions = {
this.$router.push({name:'login',params:{}}); this.$router.push({name:'login',params:{}});
reject('验证失败,重新登陆.'); reject('验证失败,重新登陆.');
} }
const { perms, name, avatar } = data; const { perms, name, avatar } = data;
// perms must be a non-empty array // perms must be a non-empty array
if (!perms || perms.length <= 0) { if (!perms || perms.length <= 0) {
reject('没有任何权限!') reject('没有任何权限!')
} }
commit('SET_PERMS', perms); commit('SET_PERMS', perms);
commit('SET_NAME', name); commit('SET_NAME', name);
commit('SET_AVATAR', avatar); commit('SET_AVATAR', avatar);
@ -118,6 +121,20 @@ const actions = {
}) })
}) })
} }
,
refreshToken({ commit },ref) {
return new Promise((resolve, reject) => {
refreshToken({refresh:ref}).then((res) => {
const { data } = res;
removeToken();
commit('SET_TOKEN', data.access);
setToken(data.access);
resolve()
}).catch(error => {
reject(error)
})
})
}
} }
export default { export default {

View File

@ -1,6 +1,6 @@
import Cookies from 'js-cookie' import Cookies from 'js-cookie'
const TokenKey = 'token' const TokenKey = 'token';
export function getToken() { export function getToken() {
return Cookies.get(TokenKey) return Cookies.get(TokenKey)
@ -14,12 +14,3 @@ export function removeToken() {
return Cookies.remove(TokenKey) return Cookies.remove(TokenKey)
} }
// export function refreshToken() {
// let token = getToken()
// let data = {"token": token}
// return request({
// url: '/token/refresh/',
// method: 'post',
// data
// })
// }

View File

@ -0,0 +1,98 @@
// 导出页面为PDF格式
import html2canvas from 'html2canvas'
import JsPDF from 'jspdf'
/*export default{
install (Vue, options) {
Vue.prototype.getPdf = function () {
var title = this.htmlTitle;
html2Canvas(document.querySelector('#pdfDom'), {
allowTaint: true
}).then(function (canvas) {
let contentWidth = canvas.width;
let contentHeight = canvas.height;
let pageHeight = contentWidth / 592.28 * 841.89;
let leftHeight = contentHeight;
let position = 0;
let imgWidth = 595.28;
let imgHeight = 592.28 / contentWidth * contentHeight;
let pageData = canvas.toDataURL('image/jpeg', 1.0);
let PDF = new JsPDF('', 'pt', 'a4');
if (leftHeight < pageHeight) {
PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
} else {
while (leftHeight > 0) {
PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
leftHeight -= pageHeight;
position -= 841.89;
if (leftHeight > 0) {
PDF.addPage()
}
}
}
PDF.save(title + '.pdf')
}
)
}
}
}*/
function downloadPDF(ele, pdfName){
let eleW = ele.offsetWidth;// 获得该容器的宽
let eleH = ele.offsetHeight;// 获得该容器的高
let eleOffsetTop = ele.offsetTop; // 获得该容器到文档顶部的距离
let eleOffsetLeft = ele.offsetLeft; // 获得该容器到文档最左的距离
var canvas = document.createElement("canvas");
var abs = 0;
let win_in = document.documentElement.clientWidth || document.body.clientWidth; // 获得当前可视窗口的宽度(不包含滚动条)
let win_out = window.innerWidth; // 获得当前窗口的宽度(包含滚动条)
if(win_out>win_in){
abs = (win_out - win_in)/2; // 获得滚动条宽度的一半
}
canvas.width = eleW * 2; // 将画布宽&&高放大两倍
canvas.height = eleH * 2;
var context = canvas.getContext("2d");
context.scale(2, 2);
context.translate(-eleOffsetLeft -abs, -eleOffsetTop);
// 这里默认横向没有滚动条的情况因为offset.left(),有无滚动条的时候存在差值,因此
// translate的时候要把这个差值去掉
html2canvas( ele, {
dpi: 300,
// allowTaint: true, //允许 canvas 污染, allowTaint参数要去掉否则是无法通过toDataURL导出canvas数据的
useCORS:true //允许canvas画布内 可以跨域请求外部链接图片, 允许跨域请求。
} ).then( (canvas)=>{
var contentWidth = canvas.width;
var contentHeight = canvas.height;
//一页pdf显示html页面生成的canvas高度;
var pageHeight = contentWidth / 592.28 * 841.89;
//未生成pdf的html页面高度
var leftHeight = contentHeight;
//页面偏移
var position = 0;
//a4纸的尺寸[595.28,841.89]html页面生成的canvas在pdf中图片的宽高
var imgWidth = 595.28;
var imgHeight = 595.28/contentWidth * contentHeight;
var pageData = canvas.toDataURL('image/jpeg', 1.0);
var pdf = new JsPDF('', 'pt', 'a4');
//有两个高度需要区分一个是html页面的实际高度和生成pdf的页面高度(841.89)
//当内容未超过pdf一页显示的范围无需分页
if (leftHeight < pageHeight) {
//在pdf.addImage(pageData, 'JPEG', 左,上,宽度,高度)设置在pdf中显示
pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight);
// pdf.addImage(pageData, 'JPEG', 20, 40, imgWidth, imgHeight);
} else { // 分页
while(leftHeight > 0) {
pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
leftHeight -= pageHeight;
position -= 841.89;
//避免添加空白页
if(leftHeight > 0) {
pdf.addPage();
}
}
}
//可动态生成
pdf.save(pdfName);
})
}
export default {
downloadPDF
}

View File

@ -1,8 +1,11 @@
import axios from 'axios' import axios from 'axios'
import { MessageBox, Message } from 'element-ui' import { MessageBox, Message } from 'element-ui'
import store from '@/store' import store from '@/store'
import { getToken } from '@/utils/auth' import { refreshToken } from '@/api/user'
import { getToken,setToken,removeToken } from '@/utils/auth'
let isRefreshing = false;
//重试队列
let requests = [];
// create an axios instance // create an axios instance
const service = axios.create({ const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
@ -56,7 +59,7 @@ service.interceptors.response.use(
* You can also judge the status by HTTP Status Code * You can also judge the status by HTTP Status Code
*/ */
response => { response => {
const res = response.data const res = response.data;
if(res.code>=200 && res.code<400){ if(res.code>=200 && res.code<400){
return res return res
} }
@ -68,18 +71,53 @@ service.interceptors.response.use(
duration: 3 * 1000 duration: 3 * 1000
}) })
}else{ }else{
MessageBox.confirm('认证失败,请重新登陆.', '确认退出', { if (!isRefreshing) {
isRefreshing = true;
//调用刷新token的接口
return refreshToken({refresh: sessionStorage.getItem('refresh')}).then(res => {
const token = res.data.access;
// 替换token
removeToken();
setToken(token);
response.headers.Authorization = 'Bearer ' + token;
// token 刷新后将数组的方法重新执行
requests.forEach((cb) => cb(token));
requests = []; // 重新请求完清空
return service(response.config)
}).catch(err => {
//跳到登录页
removeToken();
store.dispatch('user/logout').then(() => {
location.reload()
});
return Promise.reject(err)
}).finally(() => {
isRefreshing = false
})
}else {
// 返回未执行 resolve 的 Promise
return new Promise(resolve => {
// 用函数形式将 resolve 存入,等待刷新后再执行
requests.push(token => {
response.headers.Authorization = 'Bearer ' + token;
resolve(service(response.config))
})
})
}
/* MessageBox.confirm(',.', '退', {
confirmButtonText: '重新登陆', confirmButtonText: '重新登陆',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
store.dispatch('user/resetToken').then(() => { store.dispatch('user/logout').then(() => {
location.reload() location.reload()
}) })
}) })*/
} }
} else if (res.code >= 400) { } else if (res.code >= 400) {
if(res.msg.indexOf('请调整位置')>-1){
return;
}else{
Message({ Message({
message: res.msg || '请求出错', message: res.msg || '请求出错',
type: 'error', type: 'error',
@ -87,6 +125,7 @@ service.interceptors.response.use(
}) })
return Promise.reject(new Error(res.msg || '请求出错')) return Promise.reject(new Error(res.msg || '请求出错'))
} }
}
}, },
error => { error => {
// console.log(error,response) // for debug // console.log(error,response) // for debug

View File

@ -46,11 +46,12 @@
return { return {
options: {}, options: {},
cdata: { cdata: {
xData: ["冷加工", "热弯", "化学钢化"], xData: ["冷加工", "热弯","物理钢化", "化学钢化"],
seriesData: [ seriesData: [
{value: 25, name: "冷加工"}, {value: 20, name: "冷加工"},
{value: 20, name: "热弯"}, {value: 25, name: "热弯"},
{value: 30, name: "化学钢化"} {value: 30, name: "物理钢化"},
{value: 35, name: "化学钢化"}
] ]
} }
} }

View File

@ -9,10 +9,13 @@
<span class="fs-xl text mx-2">人员到岗情况</span> <span class="fs-xl text mx-2">人员到岗情况</span>
</div> </div>
</div> </div>
<div>
<div class="d-flex jc-center body-box"> <div class="d-flex jc-center body-box">
<dv-scroll-board class="dv-scr-board" :config="userConfig" /> <dv-scroll-board class="dv-scr-board" :config="userConfig" />
</div> </div>
</div> </div>
</div>
</div> </div>
</template> </template>
<script> <script>

View File

@ -135,6 +135,7 @@
export default { export default {
mixins: [drawMixin], mixins: [drawMixin],
inject:['reload'],
data() { data() {
return { return {
timing: null, timing: null,
@ -419,7 +420,7 @@
], ],
limitedTwo: false, limitedTwo: false,
configArticle: { configArticle: {
header: ['标题', '置顶', '作者', '发布时间'], header: ['标题', '置顶', '发布时间'],
data: [ data: [
['郑成功', '2022-03-05'], ['郑成功', '2022-03-05'],
['冯宝宝', '2022-03-05'] ['冯宝宝', '2022-03-05']
@ -437,6 +438,7 @@
category:[], category:[],
planData:[], planData:[],
realData:[], realData:[],
timer:null,
} }
}, },
components: { components: {
@ -476,6 +478,9 @@
that.getOneData();//车间一 that.getOneData();//车间一
that.getTwoData();//车间二 that.getTwoData();//车间二
that.getArticle(); that.getArticle();
that.timer = window.setInterval(() => {
that.reload();
},3600000)
}, },
beforeDestroy() { beforeDestroy() {
clearInterval(this.timing) clearInterval(this.timing)
@ -483,8 +488,8 @@
methods: { methods: {
timeFn() { timeFn() {
this.timing = setInterval(() => { this.timing = setInterval(() => {
this.dateDay = formatTimeBigScreen(new Date(), 'HH: mm: ss') this.dateDay = formatTimeBigScreen(new Date(), 'HH: mm: ss');
this.dateYear = formatTimeBigScreen(new Date(), 'yyyy-MM-dd') this.dateYear = formatTimeBigScreen(new Date(), 'yyyy-MM-dd');
this.dateWeek = this.weekday[new Date().getDay()] this.dateWeek = this.weekday[new Date().getDay()]
}, 1000) }, 1000)
}, },
@ -527,8 +532,19 @@
that.titleItem[3].number.number[0] = respo.data.count_selled; that.titleItem[3].number.number[0] = respo.data.count_selled;
that.titleItem[4].number.number[0] = respo.data.count_notok; that.titleItem[4].number.number[0] = respo.data.count_notok;
let mtestCount = respo.data.count_mtestok + respo.data.count_mtestnotok; let mtestCount = respo.data.count_mtestok + respo.data.count_mtestnotok;
if(respo.data.count_mtestok===0){
that.titleItem[5].number.number[0] = 0;
that.rate[0].tips = 0;
}else if(mtestCount===0){
that.titleItem[5].number.number[0] = 100;
}else{
that.titleItem[5].number.number[0] = Math.floor((respo.data.count_mtestok / mtestCount) * 100); that.titleItem[5].number.number[0] = Math.floor((respo.data.count_mtestok / mtestCount) * 100);
}
if(respo.data.count===0){
that.rate[0].tips = 100;
}else{
that.rate[0].tips = Math.floor((respo.data.count_ok / respo.data.count) * 100); that.rate[0].tips = Math.floor((respo.data.count_ok / respo.data.count) * 100);
}
//工序生产进度 //工序生产进度
getProcessNow({type: 'big_screen'}).then(res => { getProcessNow({type: 'big_screen'}).then(res => {
if (res.data) { if (res.data) {
@ -653,6 +669,7 @@
that.listUser = false; that.listUser = false;
getEmployee({page: 0,type:'big_screen',show_atwork:true}).then((response) => { getEmployee({page: 0,type:'big_screen',show_atwork:true}).then((response) => {
if (response.data) { if (response.data) {
// debugger;
let list = response.data; let list = response.data;
let data = []; let data = [];
list.forEach(item => { list.forEach(item => {
@ -660,10 +677,11 @@
obj.push(item.name); obj.push(item.name);
// obj.push(item.dept_.name); // obj.push(item.dept_.name);
if (item.is_atwork) { if (item.is_atwork) {
obj.push("<span class='colorGrass'>已到岗</span>") obj.push("<span style='display: inline-block' class='colorGrass roll-table-item'>已到岗</span>")
} else { } else {
obj.push("<span class='colorRed'>未到岗</span>") obj.push("<span style='display: inline-block' class='colorRed roll-table-item'>未到岗</span>")
} }
// obj.push(item.dept_.name);
data.push(obj) data.push(obj)
}); });
that.userConfig.data = data; that.userConfig.data = data;
@ -688,7 +706,7 @@
} else { } else {
obj.push('已置顶'); obj.push('已置顶');
} }
obj.push(item.author); // obj.push(item.author);
obj.push(item.create_time); obj.push(item.create_time);
data.push(obj) data.push(obj)
}); });
@ -703,6 +721,8 @@
that.limitedPlan = false; that.limitedPlan = false;
getPlanGantt({type: 'big_screen'}).then(res => { getPlanGantt({type: 'big_screen'}).then(res => {
if (res.code === 200) { if (res.code === 200) {
that.planData = [];
that.realData = [];
let list = res.data.results; let list = res.data.results;
list.forEach(item=>{ list.forEach(item=>{
that.category.push(item.number); that.category.push(item.number);
@ -715,6 +735,9 @@
} }
}) })
}, },
},
destroyed() {
clearInterval(this.timer)
} }
} }
</script> </script>

View File

@ -604,7 +604,6 @@
page: val, page: val,
show_atwork:true, show_atwork:true,
page_size: that.userPageSize, page_size: that.userPageSize,
fields: 'id,name,dept_name,is_atwork'
}).then((response) => { }).then((response) => {
if (response.data) { if (response.data) {
that.userList = response.data.results; that.userList = response.data.results;

View File

@ -47,21 +47,21 @@
v-el-height-adaptive-table="{bottomOffset: 42}" v-el-height-adaptive-table="{bottomOffset: 42}"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="设备名称" prop="name" width="120" show-overflow-tooltip> <el-table-column label="设备名称" prop="name" min-width="120" show-overflow-tooltip>
</el-table-column> </el-table-column>
<el-table-column label="设备编号" prop="number" width="120"> <el-table-column label="设备编号" prop="number" min-width="120">
</el-table-column> </el-table-column>
<el-table-column label="型号规格" prop="model" width="120"> <el-table-column label="型号规格" prop="model" min-width="120">
</el-table-column> </el-table-column>
<el-table-column label="生产厂及国别" prop="factory" width="120" show-overflow-tooltip> <el-table-column label="生产厂及国别" prop="factory" min-width="120" show-overflow-tooltip>
</el-table-column> </el-table-column>
<el-table-column label="生产日期" prop="production_date" width="120"> <el-table-column label="生产日期" prop="production_date" min-width="120">
</el-table-column> </el-table-column>
<el-table-column label="购置日期" prop="buy_date" width="120"> <el-table-column label="购置日期" prop="buy_date" min-width="120">
</el-table-column> </el-table-column>
<el-table-column label="数量" prop="count" width="120"> <el-table-column label="数量" prop="count" min-width="120">
</el-table-column> </el-table-column>
<el-table-column label="状态" width="120"> <el-table-column label="状态" min-width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.state===10" type="success"> <el-tag v-if="scope.row.state===10" type="success">
{{ state_[scope.row.state] }} {{ state_[scope.row.state] }}
@ -77,16 +77,16 @@
</el-tag> </el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="技术指标" width="120" show-overflow-tooltip> <el-table-column label="技术指标" min-width="120" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.parameter }}</template> <template slot-scope="scope">{{ scope.row.parameter }}</template>
</el-table-column> </el-table-column>
<el-table-column label="保管人" width="120"> <el-table-column label="保管人" min-width="120">
<template slot-scope="scope" v-if="scope.row.keeper_">{{ scope.row.keeper_.username }}</template> <template slot-scope="scope" v-if="scope.row.keeper_">{{ scope.row.keeper_.username }}</template>
</el-table-column> </el-table-column>
<el-table-column label="存放位置" width="120" show-overflow-tooltip> <el-table-column label="存放位置" min-width="120" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.place }}</template> <template slot-scope="scope">{{ scope.row.place }}</template>
</el-table-column> </el-table-column>
<el-table-column label="绑定工序" width="120" show-overflow-tooltip> <el-table-column label="绑定工序" min-width="160" show-overflow-tooltip>
<template slot-scope="scope" v-if="scope.row.step_"> <template slot-scope="scope" v-if="scope.row.step_">
<el-tag v-for="item in scope.row.step_" <el-tag v-for="item in scope.row.step_"
:key="item.number" :key="item.number"
@ -101,7 +101,7 @@
<el-table-column <el-table-column
align="center" align="center"
label="操作" label="操作"
width="120px" min-width="120px"
fixed="right" fixed="right"
> >
<template slot-scope="scope"> <template slot-scope="scope">

View File

@ -78,13 +78,13 @@
width="120px" width="120px"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <!--<el-link
v-if="checkPermission(['echeckrecord_update'])" v-if="checkPermission(['echeckrecord_update'])"
type="primary" type="primary"
@click="handleEdit(scope)" @click="handleEdit(scope)"
> >
编辑 编辑
</el-link> </el-link>-->
<el-link <el-link
v-if="checkPermission(['echeckrecord_delete'])" v-if="checkPermission(['echeckrecord_delete'])"
type="danger" type="danger"

View File

@ -99,7 +99,7 @@
</el-link> </el-link>
<el-link <el-link
v-if=" v-if="
checkPermission(['fifo_hear']) && scope.row.is_audited == false checkPermission(['fifo_audit']) && scope.row.is_audited == false
" "
type="primary" type="primary"
@click="handleAudit(scope)" @click="handleAudit(scope)"
@ -346,10 +346,12 @@
label="批次" label="批次"
:prop="'details.' + index + '.batch'" :prop="'details.' + index + '.batch'"
> >
<el-input v-model="item.batch" placeholder="批次号"></el-input> <el-input v-model="item.batch" @input="checkValueItem(index)" minlength="6" placeholder="请输入数字或字母且最小六位数"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="5" style="margin-right: 10px"> </el-row>
<el-row>
<el-col :span="5">
<el-form-item <el-form-item
class="expiration_date" class="expiration_date"
label="有效期" label="有效期"
@ -365,6 +367,21 @@
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="18">
<el-form-item label="物料编号:">
<div v-for="(ob,ind) in item.details" :key="ob.number" style="display: inline-block">
<span>{{ob.number}}</span>
<el-button
v-if="ob.number!==''"
@click="deleteItemNumber(index,ind)"
style="border: none;background: none;padding: 0;margin-top: 4px;"
>
<i class="el-icon-remove-outline" style="font-size: 20px"></i>
</el-button>
</div>
<el-input style="width: 300px;" @input="checkValue" clearable v-model="itemDetails" placeholder="物料编号,回车确定编号" @keyup.enter.native="detailEnter(itemDetails,index)"></el-input>
</el-form-item>
</el-col>
<!-- 删除按钮 --> <!-- 删除按钮 -->
<el-col :span="1"> <el-col :span="1">
<el-tooltip <el-tooltip
@ -448,6 +465,8 @@ const defaulteinventory = {
material: "", // 物料 material: "", // 物料
count: "", //数量 count: "", //数量
batch: "", //批次 batch: "", //批次
expiration_date: null, //
details:[],
}, },
], ],
}; };
@ -462,6 +481,13 @@ const defaulteoutfifo = {
export default { export default {
components: {Pagination}, components: {Pagination},
data() { data() {
const validateBatch = (rule, value, callback) => {
if (value.length < 6) {
callback(new Error("请输入不小于六位!"));
} else {
callback();
}
};
return { return {
inventory: defaulteinventory, inventory: defaulteinventory,
outfifo: defaulteoutfifo, outfifo: defaulteoutfifo,
@ -469,6 +495,7 @@ export default {
fifoList: { fifoList: {
count: 0, count: 0,
}, },
itemDetails:'',
types_: { types_: {
1: "生产领料", 1: "生产领料",
2: "销售提货", 2: "销售提货",
@ -493,6 +520,7 @@ export default {
dialogVisibles: false, dialogVisibles: false,
rule1: { rule1: {
name: [{required: true, message: "请输入", trigger: "blur"}], name: [{required: true, message: "请输入", trigger: "blur"}],
batch: [{required: true, message: "请输入不小于六位", trigger: "blur", validator: validateBatch},],
}, },
}; };
}, },
@ -506,8 +534,20 @@ export default {
this.getpuorderList(); this.getpuorderList();
}, },
methods: { methods: {
checkValue() {
this.itemDetails = this.itemDetails.replace(/[^0-9a-zA-Z]/g, '');
},
checkValueItem(index) {
this.inventory.details[index].batch = this.inventory.details[index].batch.replace(/[^0-9a-zA-Z]/g, '');
},
detailEnter(item,index){
this.inventory.details[index].details.push({number:item});
this.itemDetails = '';
},
deleteItemNumber(index,ind){
this.inventory.details[index].details.splice(ind,1);
},
checkPermission, checkPermission,
getList() { getList() {
this.listLoading = true; this.listLoading = true;
@ -582,6 +622,7 @@ export default {
material: "", // 物料 material: "", // 物料
count: "", //数量 count: "", //数量
batch: "", // 批次 batch: "", // 批次
details:[]
}); });
} else { } else {
this.$message("最多可添加十项条件"); this.$message("最多可添加十项条件");
@ -612,6 +653,8 @@ export default {
material: "", // 物料 material: "", // 物料
count: "", //数量 count: "", //数量
batch: "", //批次 batch: "", //批次
expiration_date: null, //
details:[],
}, },
]; ];
this.inventory = Object.assign({}, defaulteinventory); this.inventory = Object.assign({}, defaulteinventory);
@ -682,8 +725,28 @@ export default {
}, },
async confirm(form) { async confirm(form) {
console.log(this.inventory); let isbatch = false;
let details = [];
this.inventory.details.forEach(item=>{
if(item.batch.length<6){
isbatch = true;
}
let obj = new Object();
if(item.details.length>0){
obj = item;
}else{
obj.warehouse = item.warehouse;
obj.material = item.material;
obj.count = item.count;
obj.batch = item.batch;
obj.expiration_date = item.expiration_date;
}
details.push(obj);
});
if(isbatch){
this.$message.warning("批次号不能少于六位数");
}else{
this.inventory.details = details;
createInother(this.inventory).then((res) => { createInother(this.inventory).then((res) => {
if (res.code >= 200) { if (res.code >= 200) {
this.getList(); this.getList();
@ -691,6 +754,7 @@ export default {
this.$message.success("成功"); this.$message.success("成功");
} }
}); });
}
}, },
handleDelete(scope) { handleDelete(scope) {
this.$confirm("确认删除?", "警告", { this.$confirm("确认删除?", "警告", {

View File

@ -53,8 +53,9 @@
v-if="this.$route.params.pu_order != null" v-if="this.$route.params.pu_order != null"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.is_testok == false">不合格</el-tag> <el-tag v-if="scope.row.is_testok">合格</el-tag>
<el-tag v-else>合格</el-tag> <el-tag v-else-if="scope.row.is_testok===null">未复验</el-tag>
<el-tag v-else>不合格</el-tag>
</template> </template>
</el-table-column> </el-table-column>
@ -86,7 +87,7 @@
复验记录 复验记录
</el-link> </el-link>
<el-link <el-link
v-else-if="scope.row.need_test&&scope.row.test==[]" v-if="scope.row.need_test&&scope.row.test.length===0"
type="primary" type="primary"
@click="handleMaterial(scope)" @click="handleMaterial(scope)"
> >
@ -462,7 +463,7 @@
<el-col v-for="item in recordFieldList" :key="item.id" :span="24"> <el-col v-for="item in recordFieldList" :key="item.id" :span="24">
<div class="items" v-if="item.field_type==='draw'" style="height: 400px"> <div class="items" v-if="item.field_type==='draw'" style="height: 400px">
<span class="itemLabel">{{item.field_name}}</span> <span class="itemLabel">{{item.field_name}}</span>
<img style="width: 45%;vertical-align: text-top;" :src="'http://49.232.14.174:2222'+item.field_value"/> <img style="width: 45%;vertical-align: text-top;" :src="item.field_value"/>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>

View File

@ -14,6 +14,13 @@
:rules="loginRules" :rules="loginRules"
> >
<el-form-item prop="username"> <el-form-item prop="username">
<input
type="text"
name="username"
autocomplete="off"
onfocus="passwordType=='password'"
style="display: none;height: 0;padding: 0;"
>
<el-input <el-input
ref="username" ref="username"
v-model="loginForm.username" v-model="loginForm.username"
@ -21,16 +28,26 @@
name="username" name="username"
type="text" type="text"
tabindex="1" tabindex="1"
auto-complete="on" auto-complete="off"
><svg-icon >
<svg-icon
slot="prefix" slot="prefix"
icon-class="userName" icon-class="userName"
class="el-input__icon input-icon" class="el-input__icon input-icon"
/></el-input> />
</el-input>
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
<input
type="password"
name="password"
autocomplete="off"
onfocus="passwordType=='password'"
style="display: none;height: 0;padding: 0;"
>
<el-input <el-input
id="passwordInput"
:key="passwordType" :key="passwordType"
ref="password" ref="password"
v-model="loginForm.password" v-model="loginForm.password"
@ -38,18 +55,18 @@
placeholder="密码" placeholder="密码"
name="password" name="password"
tabindex="2" tabindex="2"
auto-complete="on" autocomplete="new-password"
id="passwordInput" auto-complete="new-password"
@keyup.enter.native="handleLogin" @keyup.enter.native="handleLogin"
><svg-icon >
<svg-icon
slot="prefix" slot="prefix"
icon-class="password" icon-class="password"
class="el-input__icon input-icon" class="el-input__icon input-icon"
/></el-input>
<span class="show-pwd" @click="showPwd">
<svg-icon
:icon-class="passwordType === 'password' ? 'eye' : 'eye-open'"
/> />
</el-input>
<span class="show-pwd" @click="showPwd">
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'"/>
</span> </span>
</el-form-item> </el-form-item>
<el-button <el-button
@ -57,8 +74,9 @@
type="primary" type="primary"
style="width: 100%; margin-bottom: 30px" style="width: 100%; margin-bottom: 30px"
@click.native.prevent="handleLogin" @click.native.prevent="handleLogin"
>登录</el-button
> >
登录
</el-button>
</el-form> </el-form>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
@ -75,8 +93,10 @@
<script> <script>
import faceLogin from '@/components/faceLogin/tracking.vue' import faceLogin from '@/components/faceLogin/tracking.vue'
export default { export default {
name: "Login", name: "Login",
inject: ['reload'],
components: { components: {
faceLogin faceLogin
}, },
@ -124,7 +144,10 @@
}; };
}, },
created() { created() {
this.getUP(); // this.getUP();
this.loginForm.username = null;
this.loginForm.password = null;
localStorage.setItem('tolerance', '0.36');
}, },
watch: { watch: {
$route: { $route: {
@ -134,6 +157,12 @@
immediate: true, immediate: true,
}, },
}, },
mounted() {
this.loginForm.username = null;
this.loginForm.password = null;
this.$refs.username = null;
this.$refs.password = null;
},
methods: { methods: {
toBigScreen() { toBigScreen() {
this.$router.push('/index') this.$router.push('/index')
@ -157,7 +186,8 @@
.dispatch("user/login", this.loginForm) .dispatch("user/login", this.loginForm)
.then(() => { .then(() => {
this.$store.dispatch("user/getCount", {}); this.$store.dispatch("user/getCount", {});
this.$router.push({ path: this.redirect || "/" }, () => {}); this.$router.push({path: this.redirect || "/"}, () => {
});
this.loading = false; this.loading = false;
localStorage.setItem("rem_username", this.loginForm.username); localStorage.setItem("rem_username", this.loginForm.username);
localStorage.setItem("rem_password", this.loginForm.password); localStorage.setItem("rem_password", this.loginForm.password);
@ -173,20 +203,13 @@
}); });
}, },
//读取cookie
getUP() {
this.loginForm.username = localStorage.getItem("rem_username");
this.loginForm.password = localStorage.getItem("rem_password");
},
//人脸登录 //人脸登录
takePhoto() { takePhoto() {
this.limitedPhoto = true; this.limitedPhoto = true;
this.openTheCamera();
}, },
/*关闭相机*/ /*关闭相机*/
closeCamera() { closeCamera() {
debugger; this.reload();
this.$refs.faceTracking.closeCamera(); this.$refs.faceTracking.closeCamera();
// this.thisVideo.srcObject.getTracks()[0].stop(); // this.thisVideo.srcObject.getTracks()[0].stop();
}, },
@ -206,11 +229,13 @@
background-image: url("../../assets/bg-login.png"); background-image: url("../../assets/bg-login.png");
background-size: cover; background-size: cover;
} }
.title { .title {
margin: 30px auto 30px auto; margin: 30px auto 30px auto;
text-align: center; text-align: center;
color: #0174d7; color: #0174d7;
} }
.logo { .logo {
width: 350px; width: 350px;
height: 140px; height: 140px;
@ -227,46 +252,56 @@
.el-input { .el-input {
height: 45px; height: 45px;
input { input {
height: 45px; height: 45px;
} }
} }
.input-icon { .input-icon {
height: 39px; height: 39px;
width: 14px; width: 14px;
margin-left: 2px; margin-left: 2px;
} }
} }
.faceLoginBtnWrap { .faceLoginBtnWrap {
width: 250px; width: 250px;
border-right: 1px dashed #409EFF; border-right: 1px dashed #409EFF;
text-align: center; text-align: center;
} }
.faceLoginBtn { .faceLoginBtn {
width: 150px; width: 150px;
margin-top: 90px; margin-top: 90px;
} }
#passwordInput { #passwordInput {
padding-right: 35px; padding-right: 35px;
} }
.show-pwd { .show-pwd {
height: 39px; height: 39px;
margin-right: 2px; margin-right: 2px;
} }
.login-tip { .login-tip {
font-size: 13px; font-size: 13px;
text-align: center; text-align: center;
color: #bfbfbf; color: #bfbfbf;
} }
.login-code { .login-code {
width: 33%; width: 33%;
height: 38px; height: 38px;
float: right; float: right;
img { img {
cursor: pointer; cursor: pointer;
vertical-align: middle; vertical-align: middle;
} }
} }
.show-pwd { .show-pwd {
position: absolute; position: absolute;
right: 10px; right: 10px;
@ -275,9 +310,11 @@
cursor: pointer; cursor: pointer;
user-select: none; user-select: none;
} }
.login-code-img { .login-code-img {
height: 38px; height: 38px;
} }
.testTracking { .testTracking {
width: 100%; width: 100%;
height: 500px; height: 500px;

View File

@ -44,9 +44,8 @@
fit fit
stripe stripe
highlight-current-row highlight-current-row
max-height="620"
height="100" height="100"
v-el-height-adaptive-table="{bottomOffset: 40}" v-el-height-adaptive-table="{bottomOffset: 50}"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="物料编号"> <el-table-column label="物料编号">
@ -85,13 +84,12 @@
>检查表 >检查表
</el-link> </el-link>
<el-link <el-link
subproduction_delete v-if="checkPermission(['material_update'])"
type="primary" type="primary"
@click="handleEdit(scope)" @click="handleEdit(scope)"
>编辑 >编辑
</el-link> </el-link>
<el-link <el-link
v-if="checkPermission(['material_update'])"
type="primary" type="primary"
@click="handledetail(scope)" @click="handledetail(scope)"
>详情 >详情
@ -134,7 +132,6 @@
<el-form-item label="规格型号"> <el-form-item label="规格型号">
<el-input v-model="material.specification" placeholder="规格型号"/> <el-input v-model="material.specification" placeholder="规格型号"/>
</el-form-item> </el-form-item>
<el-form-item label="计量单位"> <el-form-item label="计量单位">
<el-select style="width: 100%" v-model="material.unit" placeholder="请选择"> <el-select style="width: 100%" v-model="material.unit" placeholder="请选择">
<el-option <el-option
@ -146,7 +143,6 @@
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="物料类别"> <el-form-item label="物料类别">
<el-select style="width: 100%" v-model="material.type" placeholder="请选择物料类别"> <el-select style="width: 100%" v-model="material.type" placeholder="请选择物料类别">
<el-option <el-option
@ -167,6 +163,21 @@
<el-form-item label="排序"> <el-form-item label="排序">
<el-input-number style="width: 100%;" v-model="material.sort_str" :step="1" :min="0" step-strictly placeholder="排序"></el-input-number> <el-input-number style="width: 100%;" v-model="material.sort_str" :step="1" :min="0" step-strictly placeholder="排序"></el-input-number>
</el-form-item> </el-form-item>
<el-form-item label="详情文件">
<el-upload
ref="upload"
:action="upUrl"
:on-preview="handlePreview"
:on-success="handleUpSuccess"
:on-remove="handleRemove"
:headers="upHeaders"
:file-list="fileList"
:limit="1"
accept=".pdf"
>
<el-button size="small" type="primary">上传文件</el-button>
</el-upload>
</el-form-item>
</el-form> </el-form>
<div style="text-align: right"> <div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button> <el-button type="danger" @click="dialogVisible = false">取消</el-button>
@ -185,9 +196,8 @@
getProcessList getProcessList
} from "@/api/mtm"; } from "@/api/mtm";
import checkPermission from "@/utils/permission"; import checkPermission from "@/utils/permission";
import {genTree} from "@/utils"; import {genTree} from "@/utils";
import {upUrl, upHeaders} from "@/api/file";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaultmaterial = { const defaultmaterial = {
name: null, name: null,
@ -199,6 +209,7 @@
sort_str: null, sort_str: null,
count_safe: 0, count_safe: 0,
processes: [], processes: [],
file:null,
}; };
export default { export default {
components: {Pagination}, components: {Pagination},
@ -208,6 +219,9 @@
materialList: { materialList: {
count: 0, count: 0,
}, },
upHeaders: upHeaders(),
upUrl: upUrl(),
fileList: [],
processOptions: [], processOptions: [],
options_: { options_: {
// "1": '成品', // "1": '成品',
@ -246,8 +260,7 @@
}, { }, {
value: '', value: '',
label: '' label: ''
}, }, {
{
value: '', value: '',
label: '' label: ''
}, { }, {
@ -256,6 +269,27 @@
}, { }, {
value: '', value: '',
label: '' label: ''
}, {
value: 'g',
label: 'g'
}, {
value: 'kg',
label: 'kg'
}, {
value: '',
label: ''
}, {
value: '',
label: ''
}, {
value: '',
label: ''
}, {
value: '',
label: ''
}, {
value: '',
label: ''
}, },
], ],
listQuery: { listQuery: {
@ -282,6 +316,19 @@
}, },
methods: { methods: {
checkPermission, checkPermission,
handlePreview(file) {
if ("url" in file) {
window.open(file.url);
} else {
window.open(file.response.data.path);
}
},
handleUpSuccess(res, file, filelist) {
this.material.file = res.data.id;
},
handleRemove(file, filelist) {
this.material.file = null;
},
//物料详情 //物料详情
handledetail(scope){ handledetail(scope){
this.$router.push({name: "MaterialDetail", params: { id: scope.row.id,type: scope.row.type }, }) this.$router.push({name: "MaterialDetail", params: { id: scope.row.id,type: scope.row.type }, })
@ -312,9 +359,23 @@
this.processOptions = res.data.results; this.processOptions = res.data.results;
}); });
}, },
//绑定工序 //检查表
handlebind(scope) { handlebind(scope) {
this.$router.push({name: "MaterialDO", params: {id: scope.row.id},}) let materialItem = sessionStorage.getItem('materialItem');
let materialType = sessionStorage.getItem('materialType');
if(materialItem){
sessionStorage.removeItem('materialItem');
sessionStorage.setItem('materialItem',JSON.stringify(scope.row));
}else{
sessionStorage.setItem('materialItem',JSON.stringify(scope.row));
}
if(materialType){
sessionStorage.removeItem('materialType');
sessionStorage.setItem('materialType','30');
}else{
sessionStorage.setItem('materialType','30');
}
this.$router.push({name: "MaterialDO", params: {id: scope.row.id}})
}, },
handleFilter() { handleFilter() {
this.listQuery.page = 1; this.listQuery.page = 1;
@ -332,14 +393,31 @@
this.material = Object.assign({}, defaultmaterial); this.material = Object.assign({}, defaultmaterial);
this.dialogType = "new"; this.dialogType = "new";
this.dialogVisible = true; this.dialogVisible = true;
if (this.material.file) {
this.fileList = [
{
name: this.process.instruction_.name,
url: this.process.instruction_.path,
},
];
}
this.$nextTick(() => { this.$nextTick(() => {
this.$refs["Form"].clearValidate(); this.$refs["Form"].clearValidate();
}); });
}, },
handleEdit(scope) { handleEdit(scope) {
this.fileList = [];
this.material = Object.assign({}, scope.row); // copy obj this.material = Object.assign({}, scope.row); // copy obj
this.dialogType = "edit"; this.dialogType = "edit";
this.dialogVisible = true; this.dialogVisible = true;
if (this.material.file) {
this.fileList = [
{
name: this.material.file_.name,
url: this.material.file_.path,
},
];
}
this.$nextTick(() => { this.$nextTick(() => {
this.$refs["Form"].clearValidate(); this.$refs["Form"].clearValidate();
}); });
@ -368,6 +446,7 @@
if (res.code >= 200) { if (res.code >= 200) {
this.getList(); this.getList();
this.dialogVisible = false; this.dialogVisible = false;
this.fileList = [];
this.$message.success("成功"); this.$message.success("成功");
} }
}); });
@ -376,6 +455,7 @@
if (res.code >= 200) { if (res.code >= 200) {
this.getList(); this.getList();
this.dialogVisible = false; this.dialogVisible = false;
this.fileList = [];
this.$message.success("成功"); this.$message.success("成功");
} }
}); });

View File

@ -9,28 +9,31 @@
border border
> >
<el-descriptions-item label="物料编号"> <el-descriptions-item label="物料编号">
{{ materialdetail.number }}</el-descriptions-item {{ materialdetail.number }}
> </el-descriptions-item>
<el-descriptions-item label="物料名称"> <el-descriptions-item label="物料名称">
{{ materialdetail.name }}</el-descriptions-item {{ materialdetail.name }}
> </el-descriptions-item>
<el-descriptions-item label="规格型号" :span="2"> <el-descriptions-item label="规格型号" :span="2">
{{ materialdetail.specification }}</el-descriptions-item {{ materialdetail.specification }}
> </el-descriptions-item>
<el-descriptions-item label="计量单位"> <el-descriptions-item label="计量单位">
{{ materialdetail.unit }} {{ materialdetail.unit }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="数量"> <el-descriptions-item label="数量">
{{ materialdetail.count }}</el-descriptions-item {{ materialdetail.count }}
> </el-descriptions-item>
<el-descriptions-item label="文件">
<el-link v-if="materialdetail.file_" :href="materialdetail.file_.path">{{materialdetail.file_.name}}
</el-link>
</el-descriptions-item>
</el-descriptions> </el-descriptions>
</el-card> </el-card>
<el-tabs v-model="activeName" type="card"> <el-tabs v-model="activeName" type="card">
<el-tab-pane <el-tab-pane
v-if="this.type == 3 || this.type == 4"
label="供应商" label="供应商"
name="5" name="5"
v-if="this.type == 3 || this.type == 4"
> >
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="批次" name="3"> <el-tab-pane label="批次" name="3">
@ -47,37 +50,25 @@
<template slot-scope="scope">{{ scope.row.batch }}</template> <template slot-scope="scope">{{ scope.row.batch }}</template>
</el-table-column> </el-table-column>
<el-table-column label="物料名称"> <el-table-column label="物料名称">
<template slot-scope="scope">{{ <template slot-scope="scope">{{scope.row.material_.name}}</template>
scope.row.material_.name
}}</template>
</el-table-column> </el-table-column>
<el-table-column label="规格型号"> <el-table-column label="规格型号">
<template slot-scope="scope">{{ <template slot-scope="scope">{{scope.row.material_.specification}}</template>
scope.row.material_.specification
}}</template>
</el-table-column> </el-table-column>
<el-table-column label="物料编号"> <el-table-column label="物料编号">
<template slot-scope="scope">{{ <template slot-scope="scope">{{scope.row.material_.number}}</template>
scope.row.material_.number
}}</template>
</el-table-column> </el-table-column>
<el-table-column label="仓库名称"> <el-table-column label="仓库名称">
<template slot-scope="scope">{{ <template slot-scope="scope">{{scope.row.warehouse_.name}}</template>
scope.row.warehouse_.name
}}</template>
</el-table-column> </el-table-column>
<el-table-column label="仓库编号"> <el-table-column label="仓库编号">
<template slot-scope="scope">{{ <template slot-scope="scope">{{scope.row.warehouse_.number}}</template>
scope.row.warehouse_.number
}}</template>
</el-table-column> </el-table-column>
<el-table-column label="物料总存量"> <el-table-column label="物料总存量">
<template slot-scope="scope">{{ scope.row.count }}</template> <template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="关联的订单" name="1"> <el-tab-pane label="关联的订单" name="1">
<el-table <el-table
:data="orderlist" :data="orderlist"
@ -95,22 +86,26 @@
<el-table-column label="客户" show-overflow-tooltip> <el-table-column label="客户" show-overflow-tooltip>
<template slot-scope="scope">{{ <template slot-scope="scope">{{
scope.row.customer_.name scope.row.customer_.name
}}</template> }}
</template>
</el-table-column> </el-table-column>
<el-table-column label="所属合同" show-overflow-tooltip> <el-table-column label="所属合同" show-overflow-tooltip>
<template slot-scope="scope">{{ <template slot-scope="scope">{{
scope.row.contract_.name scope.row.contract_.name
}}</template> }}
</template>
</el-table-column> </el-table-column>
<el-table-column label="产品名称" show-overflow-tooltip> <el-table-column label="产品名称" show-overflow-tooltip>
<template slot-scope="scope">{{ <template slot-scope="scope">{{
scope.row.product_.name scope.row.product_.name
}}</template> }}
</template>
</el-table-column> </el-table-column>
<el-table-column label="产品型号" show-overflow-tooltip> <el-table-column label="产品型号" show-overflow-tooltip>
<template slot-scope="scope">{{ <template slot-scope="scope">{{
scope.row.product_.specification scope.row.product_.specification
}}</template> }}
</template>
</el-table-column> </el-table-column>
<el-table-column label="产品数量"> <el-table-column label="产品数量">
<template slot-scope="scope">{{ scope.row.count }}</template> <template slot-scope="scope">{{ scope.row.count }}</template>
@ -118,12 +113,14 @@
<el-table-column label="交货日期"> <el-table-column label="交货日期">
<template slot-scope="scope">{{ <template slot-scope="scope">{{
scope.row.delivery_date scope.row.delivery_date
}}</template> }}
</template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间"> <el-table-column label="创建时间">
<template slot-scope="scope">{{ <template slot-scope="scope">{{
scope.row.create_time scope.row.create_time
}}</template> }}
</template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-tab-pane> </el-tab-pane>
@ -144,12 +141,14 @@
<el-table-column label="订单编号"> <el-table-column label="订单编号">
<template slot-scope="scope">{{ <template slot-scope="scope">{{
scope.row.order_.number scope.row.order_.number
}}</template> }}
</template>
</el-table-column> </el-table-column>
<el-table-column label="合同编号"> <el-table-column label="合同编号">
<template slot-scope="scope">{{ <template slot-scope="scope">{{
scope.row.order_.contract_.number scope.row.order_.contract_.number
}}</template> }}
</template>
</el-table-column> </el-table-column>
<el-table-column label="生产数量"> <el-table-column label="生产数量">
@ -164,7 +163,8 @@
<el-table-column label="交付截止时间"> <el-table-column label="交付截止时间">
<template slot-scope="scope">{{ <template slot-scope="scope">{{
scope.row.order_.delivery_date scope.row.order_.delivery_date
}}</template> }}
</template>
</el-table-column> </el-table-column>
<el-table-column label="是否生成子计划"> <el-table-column label="是否生成子计划">
@ -176,7 +176,8 @@
<el-table-column label="创建时间"> <el-table-column label="创建时间">
<template slot-scope="scope">{{ <template slot-scope="scope">{{
scope.row.create_time scope.row.create_time
}}</template> }}
</template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-tab-pane> </el-tab-pane>
@ -205,18 +206,24 @@
<el-table-column label="状态"> <el-table-column label="状态">
<template slot-scope="scope">{{ <template slot-scope="scope">{{
actstate_[scope.row.act_state] actstate_[scope.row.act_state]
}}</template> }}
</template>
</el-table-column> </el-table-column>
<el-table-column label="仓库"> <el-table-column label="仓库">
<template slot-scope="scope" v-if="scope.row.warehouse_">{{ <template slot-scope="scope" v-if="scope.row.warehouse_">{{
scope.row.warehouse_.name scope.row.warehouse_.name
}}</template> }}
</template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="装箱单" name="5" v-if="this.type == 1"> <el-tab-pane label="装箱单" name="5" v-if="this.type == 1">
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"> <el-button
v-if="checkPermission(['packitem_create'])"
type="primary"
icon="el-icon-plus"
@click="handleCreate"
>
新增装箱单 新增装箱单
</el-button> </el-button>
<el-table <el-table
@ -228,19 +235,14 @@
height="460" height="460"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="名称"> <el-table-column label="名称">
<template slot-scope="scope">{{ scope.row.name }}</template> <template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="单位"> <el-table-column label="单位">
<template slot-scope="scope">{{ scope.row.unit }}</template> <template slot-scope="scope">{{ scope.row.unit }}</template>
</el-table-column> </el-table-column>
<el-table-column label="数量"> <el-table-column label="数量">
<template slot-scope="scope" >{{ <template slot-scope="scope">{{scope.row.count}}</template>
scope.row.count
}}</template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
align="center" align="center"
@ -248,19 +250,19 @@
width="220px" width="220px"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
v-if="checkPermission(['packitem_update'])"
type="primary" type="primary"
@click="handleEdit(scope)" @click="handleEdit(scope)"
>编辑 >
编辑
</el-link> </el-link>
<el-link <el-link
v-if="checkPermission(['packitem_delete'])"
type="danger" type="danger"
@click="handleDelete(scope)" @click="handleDelete(scope)"
>删除 >
删除
</el-link> </el-link>
</template> </template>
</el-table-column> </el-table-column>
@ -284,9 +286,10 @@
<el-option <el-option
v-for="item in materialoptions" v-for="item in materialoptions"
:key="item.id" :key="item.id"
:value="item.id"
:label="item.name" :label="item.name"
> :value="item.id">
<span style="float: left">{{ item.name }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ item.specification }}</span>
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -318,9 +321,12 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<div style="text-align: right"> <div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false" <el-button
>取消</el-button type="danger"
@click="dialogVisible = false"
> >
取消
</el-button>
<el-button type="primary" @click="confirm('Form')">确认</el-button> <el-button type="primary" @click="confirm('Form')">确认</el-button>
</div> </div>
</el-dialog> </el-dialog>
@ -337,7 +343,14 @@ import { upUrl, upHeaders } from "@/api/file";
import {getProductionplanList} from "@/api/pm"; import {getProductionplanList} from "@/api/pm";
import {getmaterialbatchList} from "@/api/inm"; import {getmaterialbatchList} from "@/api/inm";
import {getOrderList} from "@/api/sam"; import {getOrderList} from "@/api/sam";
import { getMaterial,getpackitemList,createpackitem,updatepackitem,deletepackitem,getMaterialList } from "@/api/mtm"; import {
getMaterial,
getpackitemList,
createpackitem,
updatepackitem,
deletepackitem,
getMaterialList
} from "@/api/mtm";
import {getwproductList} from "@/api/wpm"; import {getwproductList} from "@/api/wpm";
import {upFile} from "@/api/file"; import {upFile} from "@/api/file";
@ -345,6 +358,7 @@ import { genTree } from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
import Treeselect from "@riophae/vue-treeselect"; import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css"; import "@riophae/vue-treeselect/dist/vue-treeselect.css";
const defaultpackitem = { const defaultpackitem = {
name: "", name: "",
unit: "", unit: "",
@ -389,7 +403,7 @@ export default {
created() { created() {
this.material = this.$route.params.id; this.material = this.$route.params.id;
this.type = this.$route.params.type; this.type = this.$route.params.type;
this.getMaterialist() this.getMaterialist();
this.getMaterial(); this.getMaterial();
this.getpickList(); this.getpickList();
this.getOrderList(); this.getOrderList();
@ -398,14 +412,13 @@ export default {
this.getwproductList(); this.getwproductList();
}, },
methods: { methods: {
checkPermission,
//新增装箱单 //新增装箱单
getMaterialist() getMaterialist() {
{
getMaterialList({pageoff: true, type: 3}).then((response) => { getMaterialList({pageoff: true, type: 3}).then((response) => {
if (response.data) { if (response.data) {
this.materialoptions = response.data; this.materialoptions = response.data;
} }
}); });
}, },
@ -415,15 +428,10 @@ selectmaterial(selval){
this.packitem.name = response.data.name; this.packitem.name = response.data.name;
this.packitem.unit = response.data.unit; this.packitem.unit = response.data.unit;
this.packitem.specification = response.data.specification; this.packitem.specification = response.data.specification;
} }
}); });
}, },
handleCreate() { handleCreate() {
this.packitem = Object.assign({}, defaultpackitem); this.packitem = Object.assign({}, defaultpackitem);
this.dialogType = "new"; this.dialogType = "new";
@ -440,6 +448,7 @@ handleCreate() {
this.$refs["Form"].clearValidate(); this.$refs["Form"].clearValidate();
}); });
}, },
handleDelete(scope) { handleDelete(scope) {
this.$confirm("确认删除?", "警告", { this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认", confirmButtonText: "确认",
@ -455,6 +464,7 @@ handleCreate() {
console.error(err); console.error(err);
}); });
}, },
async confirm(form) { async confirm(form) {
this.$refs[form].validate((valid) => { this.$refs[form].validate((valid) => {
if (valid) { if (valid) {
@ -483,8 +493,7 @@ handleCreate() {
}); });
}, },
getpickList() getpickList() {
{
getpackitemList({product: this.material, page: 0}).then((response) => { getpackitemList({product: this.material, page: 0}).then((response) => {
if (response.data) { if (response.data) {
this.pickList = response.data; //zhuangxiang信息 this.pickList = response.data; //zhuangxiang信息
@ -495,6 +504,7 @@ getpickList()
getMaterial() { getMaterial() {
getMaterial(this.material).then((response) => { getMaterial(this.material).then((response) => {
if (response.data) { if (response.data) {
// debugger;
this.materialdetail = response.data; //物料基本信息 this.materialdetail = response.data; //物料基本信息
} }
}); });
@ -506,6 +516,7 @@ getpickList()
} }
}); });
}, },
getplanList() { getplanList() {
getProductionplanList({material: this.material, page: 0}).then( getProductionplanList({material: this.material, page: 0}).then(
(response) => { (response) => {

View File

@ -1,6 +1,14 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-card> <el-card>
<el-card style="margin-top: 2px">
<el-descriptions title="物料详情" :column="4" border style="margin-bottom: 10px">
<el-descriptions-item label="编号">{{item.number}}</el-descriptions-item>
<el-descriptions-item label="类别">{{materialTypes[item.type]}}</el-descriptions-item>
<el-descriptions-item label="名称">{{item.name}}</el-descriptions-item>
<el-descriptions-item label="规格型号">{{item.specification}}</el-descriptions-item>
</el-descriptions>
</el-card>
<el-row :gutter="2"> <el-row :gutter="2">
<!--表格--> <!--表格-->
<el-col :span="10"> <el-col :span="10">
@ -113,6 +121,20 @@
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="表单模板" prop="template">
<el-upload
ref="upload"
:action="upUrl"
:on-success="handleUpSuccess"
:on-remove="handleRemove"
:headers="upHeaders"
:file-list="fileList"
:limit="1"
accept=".docx"
>
<el-button size="small" type="primary">上传模板</el-button>
</el-upload>
</el-form-item>
<el-form-item label="是否启用" prop="name"> <el-form-item label="是否启用" prop="name">
<el-switch v-model="recordform.enabled"></el-switch> <el-switch v-model="recordform.enabled"></el-switch>
</el-form-item> </el-form-item>
@ -132,7 +154,8 @@
:title="tableForm.name" :title="tableForm.name"
> >
<customForm <customForm
:results="fieldList.results" v-if="dialogVisibleForm"
:results="dialogFieldList"
:hasPicture="hasPicture" :hasPicture="hasPicture"
:formID="formID" :formID="formID"
:isDisabled="isDisabled" :isDisabled="isDisabled"
@ -435,9 +458,9 @@
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="字段父级"> <!--<el-form-item label="字段父级">
<treeselect v-model="field.parent" :multiple="false" :options="treeDate" placeholder="字段父级"/> <treeselect v-model="field.parent" :multiple="false" :options="treeDate" placeholder="字段父级"/>
</el-form-item> </el-form-item>-->
<el-form-item label="字段说明"> <el-form-item label="字段说明">
<el-input v-model="field.help_text" placeholder="字段名称"/> <el-input v-model="field.help_text" placeholder="字段名称"/>
</el-form-item> </el-form-item>
@ -519,23 +542,21 @@
import {upFile} from "@/api/file"; import {upFile} from "@/api/file";
import {genTree} from "@/utils"; import {genTree} from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
import Treeselect from '@riophae/vue-treeselect' import Treeselect from '@riophae/vue-treeselect';
import '@riophae/vue-treeselect/dist/vue-treeselect.css' import '@riophae/vue-treeselect/dist/vue-treeselect.css';
const defaultstep = { const defaultstep = {
name: "", name: "",
number: "", number: "",
}; };
const defaultrecordform = {enabled: false}; const defaultrecordform = {enabled: false};
const defaultfield = {};
let preDrawAry = [];
export default { export default {
components: {Pagination, vueJsonEditor, Treeselect, customForm, faceLogin}, components: {Pagination,customForm, faceLogin},
data() { data() {
return { return {
item:{},
step: defaultstep, step: defaultstep,
stepList: [], stepList: [],
dialogFieldList: [],
upHeaders: upHeaders(), upHeaders: upHeaders(),
upUrl: upUrl(), upUrl: upUrl(),
fileList: [], fileList: [],
@ -575,7 +596,7 @@
}, },
listQueryrecordform: { listQueryrecordform: {
page: 1, page: 1,
page_size: 20, page_size: 99,
}, },
recordformList: { recordformList: {
count: 0, count: 0,
@ -673,10 +694,19 @@
], ],
typeOptions_:{ typeOptions_:{
10 : "生产记录表", 10 : "生产记录表",
20 : "工序检查表", 20 : "工序检查表",//wp p
30 : "入厂检验表", 30 : "入厂检验表",//wuliao
40 : "成品检验表", 40 : "成品检验表",//p
50 : "首件检查表", 50 : "首件检查表",//wp
},
materialTypes: {
"1": '成品',
"2": '半成品',
"3": '主要原料',
"4": '辅助材料',
"5": '加工工具',
"6": '辅助工装',
}, },
canvas: null, canvas: null,
ctx: null, ctx: null,
@ -693,15 +723,21 @@
judgeList: [], judgeList: [],
limitedPhoto: false, limitedPhoto: false,
isDisabled: true, isDisabled: true,
type:null,
}; };
}, },
computed: {}, computed: {},
watch: {}, watch: {},
created() {
this.material = this.$route.params.id;
this.recordformLists();
},
mounted(){ mounted(){
this.item = JSON.parse(sessionStorage.getItem('materialItem')) ;
let type = sessionStorage.getItem('materialType') ;
if(type.indexOf(','>0)){
this.type = type.split(',');
}else{
this.type = parseInt(type);
}
this.material = this.item.id;
this.recordformLists();
getrecordformList({page:0}).then((response) => { getrecordformList({page:0}).then((response) => {
if (response.data) { if (response.data) {
this.formList = response.data; this.formList = response.data;
@ -709,6 +745,19 @@
}); });
}, },
methods: { methods: {
/* handlePreview(file) {
if ("url" in file) {
window.open(file.url);
} else {
window.open(file.response.data.path);
}
},*/
handleUpSuccess(res) {
this.recordform.export_template = res.data.path;
},
handleRemove() {
this.recordform.export_template = '';
},
formFunc(value) { formFunc(value) {
this.dialogVisibleForm = value; this.dialogVisibleForm = value;
}, },
@ -795,7 +844,7 @@
} }
}, },
checkValue() { checkValue() {
this.field.field_key = this.field.field_key.replace(/[^a-zA-Z]/g, ''); this.field.field_key = this.field.field_key.replace(/[^0-9a-zA-Z]/g, '');
}, },
//添加字段选项 //添加字段选项
addDomain() { addDomain() {
@ -805,16 +854,23 @@
removeDomain(index) { removeDomain(index) {
this.field_choice.splice(index, 1); this.field_choice.splice(index, 1);
}, },
handleLook(scope) { async handleLook(scope) {
debugger;
let that = this; let that = this;
this.dialogFieldList=[];
that.tableForm = Object.assign({}, scope.row); // copy obj that.tableForm = Object.assign({}, scope.row); // copy obj
that.formID = that.tableForm.id; that.formID = that.tableForm.id;
that.listQueryfield.form = that.formID; that.listQueryfield.form = that.formID;
getrffieldList(that.listQueryfield).then((response) => { getrffieldList(that.listQueryfield).then((response) => {
if (response.data) { if (response.data) {
this.hasPicture = false;
that.fieldList = response.data; that.fieldList = response.data;
let list = response.data.results; }
});
await getrffieldList({page:0,form:that.formID}).then((response) => {
if (response.data) {
this.hasPicture = false;
let list = response.data;
this.dialogFieldList= response.data;
let arr = list.filter(item => { let arr = list.filter(item => {
return item.field_type === 'draw' return item.field_type === 'draw'
}); });
@ -837,12 +893,8 @@
that.$set(that.checkForm, key, '') that.$set(that.checkForm, key, '')
} }
that.dialogVisibleForm = true; that.dialogVisibleForm = true;
/* setTimeout(function () {
that.canvasInit();
}, 500);*/
} }
}); });
that.fieldLists();
}, },
checkPermission, checkPermission,
handleCurrentChange(row) { handleCurrentChange(row) {
@ -851,13 +903,32 @@
this.fieldLists1(); this.fieldLists1();
}, },
recordformLists() { recordformLists() {
this.listQueryrecordform.material = this.material; debugger;
// this.listQueryrecordform.type = 2; let that = this;
getrecordformList(this.listQueryrecordform).then((response) => { that.listQueryrecordform.material = that.material;
if(that.type===10){
debugger;
that.listQueryrecordform.type = 10;
getrecordformList(that.listQueryrecordform).then((response) => {
if (response.data) { if (response.data) {
this.recordformList = response.data; that.recordformList = response.data;
} }
}); });
}else{
debugger;
that.listQueryrecordform.type = that.type[0];
getrecordformList(that.listQueryrecordform).then((response) => {
if (response.data) {
that.recordformList = response.data;
that.listQueryrecordform.type = that.type[1];
getrecordformList(that.listQueryrecordform).then((response) => {
if (response.data) {
that.recordformList.results = that.recordformList.results.concat(response.data.results);
}
});
}
});
}
}, },
fieldLists() { fieldLists() {
let that = this; let that = this;
@ -927,6 +998,14 @@
this.recordform = Object.assign({}, scope.row); // copy obj this.recordform = Object.assign({}, scope.row); // copy obj
this.dialogType = "edit"; this.dialogType = "edit";
this.dialogVisible = true; this.dialogVisible = true;
if (this.recordform.export_template) {
this.fileList = [
{
name: this.recordform.export_template,
url: this.recordform.export_template,
},
];
}
this.$nextTick(() => { this.$nextTick(() => {
this.$refs["Forms"].clearValidate(); this.$refs["Forms"].clearValidate();
}); });
@ -979,6 +1058,7 @@
obj.name=this.recordform.name; obj.name=this.recordform.name;
obj.type=this.recordform.type; obj.type=this.recordform.type;
obj.enabled=this.recordform.enabled; obj.enabled=this.recordform.enabled;
obj.export_template=this.recordform.export_template?this.recordform.export_template:'';
if (isEdit) { if (isEdit) {
obj.form=this.recordform.form?this.recordform.form:null; obj.form=this.recordform.form?this.recordform.form:null;
updaterecordform(this.recordform.id, obj).then( updaterecordform(this.recordform.id, obj).then(

View File

@ -14,9 +14,9 @@
border border
fit fit
stripe stripe
max-height="620"
height="100" height="100"
v-el-height-adaptive-table="{bottomOffset: 10}" highlight-current-row
v-el-height-adaptive-table="{bottomOffset: 50}"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="工序编号"> <el-table-column label="工序编号">

View File

@ -216,8 +216,7 @@
}, { }, {
value: '', value: '',
label: '' label: ''
}, }, {
{
value: '', value: '',
label: '' label: ''
}, { }, {
@ -226,6 +225,27 @@
}, { }, {
value: '', value: '',
label: '' label: ''
}, {
value: 'g',
label: 'g'
}, {
value: 'kg',
label: 'kg'
}, {
value: '',
label: ''
}, {
value: '',
label: ''
}, {
value: '',
label: ''
}, {
value: '',
label: ''
},{
value: '',
label: ''
}, },
], ],
listQuery: { listQuery: {
@ -268,7 +288,21 @@
}, },
//检查表 //检查表
handlebind(scope) { handlebind(scope) {
this.$router.push({name: "MaterialDO", params: {id: scope.row.id},}) let materialItem = sessionStorage.getItem('materialItem');
let materialType = sessionStorage.getItem('materialType');
if(materialItem){
sessionStorage.removeItem('materialItem');
sessionStorage.setItem('materialItem',JSON.stringify(scope.row));
}else{
sessionStorage.setItem('materialItem',JSON.stringify(scope.row));
}
if(materialType){
sessionStorage.removeItem('materialType');
sessionStorage.setItem('materialType','20,40');
}else{
sessionStorage.setItem('materialType','20,40');
}
this.$router.push({name: "MaterialDO", params: {id: scope.row.id}})
}, },
handleFilter() { handleFilter() {
this.listQuery.page = 1; this.listQuery.page = 1;

View File

@ -14,33 +14,26 @@
border border
fit fit
stripe stripe
height="100"
@current-change="handleCurrentChange"
highlight-current-row highlight-current-row
height="660px" v-el-height-adaptive-table="{bottomOffset: 10}"
@current-change="handleCurrentChange"> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="产品编号"> <el-table-column label="产品编号">
<template slot-scope="scope">{{ scope.row.number }}</template> <template slot-scope="scope">{{ scope.row.number }}</template>
</el-table-column> </el-table-column>
<el-table-column label="产品名称" width="200px"> <el-table-column label="产品名称" width="200px">
<template slot-scope="scope">{{ scope.row.name }}</template> <template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="规格型号"> <el-table-column label="规格型号">
<template slot-scope="scope">{{ scope.row.specification }}</template> <template slot-scope="scope">{{ scope.row.specification }}</template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-card> </el-card>
</el-col> </el-col>
<el-col :span="15"> <el-col :span="15">
<el-card class="box-card"> <el-card class="box-card" id="processCard">
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<span style="font-size: 16px; <span style="font-size: 16px;
font-weight: 700; font-weight: 700;
@ -62,11 +55,12 @@
font-weight: 700; font-weight: 700;
">流程分解</span> ">流程分解</span>
</div> </div>
<el-button v-if="checkPermission(['subproduction_create'])" type="primary" icon="el-icon-plus" @click="handlesubproducationCreate"> <el-button v-if="checkPermission(['subproduction_create'])" type="primary" icon="el-icon-plus"
@click="handlesubproducationCreate">
新增 新增
</el-button> </el-button>
<el-table <el-table
height="190px" :height="halfHeight"
:data="subproducationData" :data="subproducationData"
border border
fit fit
@ -153,7 +147,7 @@
</div> </div>
</el-dialog> </el-dialog>
</el-card> </el-card>
<el-tabs type="border-card" style="height:310px"> <el-tabs type="border-card">
<el-tab-pane label="输入物料"> <el-tab-pane label="输入物料">
<el-button <el-button
v-if="checkPermission(['subproduction_update'])" v-if="checkPermission(['subproduction_update'])"
@ -168,7 +162,7 @@
border border
fit fit
stripe stripe
height="220px" :height="halfHeight"
style="width: 100%;" style="width: 100%;"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
@ -181,6 +175,9 @@
<el-table-column label="计量单位" min-width="100"> <el-table-column label="计量单位" min-width="100">
<template slot-scope="scope">{{ scope.row.material_.unit }}</template> <template slot-scope="scope">{{ scope.row.material_.unit }}</template>
</el-table-column> </el-table-column>
<el-table-column label="规格" min-width="100">
<template slot-scope="scope">{{ scope.row.material_.specification }}</template>
</el-table-column>
<el-table-column label="单位消耗量" min-width="100"> <el-table-column label="单位消耗量" min-width="100">
<template slot-scope="scope">{{ scope.row.count }}</template> <template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column> </el-table-column>
@ -259,6 +256,7 @@
border border
fit fit
stripe stripe
:height="halfHeight"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="物料编号"> <el-table-column label="物料编号">
@ -359,6 +357,7 @@
fit fit
stripe stripe
style="width: 100%" style="width: 100%"
:height="halfHeight"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="物料编号" min-width="100"> <el-table-column label="物料编号" min-width="100">
@ -447,6 +446,7 @@
border border
fit fit
stripe stripe
:height="halfHeight"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="子工序名称"> <el-table-column label="子工序名称">
@ -458,6 +458,12 @@
<span v-else>不检验</span> <span v-else>不检验</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="复用上表">
<template slot-scope="scope">
<span v-if=" scope.row.reuse_form"></span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="备注"> <el-table-column label="备注">
<template slot-scope="scope">{{ scope.row.remark }}</template> <template slot-scope="scope">{{ scope.row.remark }}</template>
</el-table-column> </el-table-column>
@ -500,12 +506,6 @@
label-width="100px" label-width="100px"
label-position="right" label-position="right"
> >
<el-form-item label="工序内检验">
<el-radio-group v-model="usedstep.need_test">
<el-radio :label="true">检验</el-radio>
<el-radio :label="false">不检验</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="子工序" prop="unit"> <el-form-item label="子工序" prop="unit">
<el-select style="width: 100%" v-model="usedstep.step" placeholder="请选择"> <el-select style="width: 100%" v-model="usedstep.step" placeholder="请选择">
<el-option <el-option
@ -516,6 +516,18 @@
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="工序内检验">
<el-radio-group v-model="usedstep.need_test">
<el-radio :label="true">检验</el-radio>
<el-radio :label="false">不检验</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="复用上表">
<el-radio-group v-model="usedstep.reuse_form">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item label="备注" prop="remark">
<el-input v-model="usedstep.remark" placeholder="输入备注信息"/> <el-input v-model="usedstep.remark" placeholder="输入备注信息"/>
</el-form-item> </el-form-item>
@ -536,6 +548,7 @@
新增 新增
</el-button> </el-button>
<el-table <el-table
:height="halfHeight"
:data="techdoctableData" :data="techdoctableData"
border border
fit fit
@ -632,8 +645,7 @@
getMaterial, getMaterial,
getInputmaterialList, getInputmaterialList,
createInputmaterial, createInputmaterial,
updateInputmaterial updateInputmaterial,
,
deleteInputmaterial, deleteInputmaterial,
getOutputmaterialList, getOutputmaterialList,
createOutputmaterial, createOutputmaterial,
@ -647,8 +659,7 @@
gettechdocList, gettechdocList,
createtechdoc, createtechdoc,
updatetechdoc, updatetechdoc,
deletetechdoc deletetechdoc,
,
getsubproducationList, getsubproducationList,
createsubproducation, createsubproducation,
updatesubproducation, updatesubproducation,
@ -683,6 +694,7 @@
data() { data() {
return { return {
halfHeight: null,
materialoptions: [], materialoptions: [],
subproducationData: [], subproducationData: [],
inputtableData: [], inputtableData: [],
@ -756,6 +768,13 @@
created() { created() {
this.getList(); this.getList();
}, },
mounted() {
let that = this;
let hei = document.getElementsByClassName('app-main')[0].clientHeight;
let h = document.getElementById('processCard').clientHeight;
that.halfHeight = (hei - h - 176) / 2;
this.getmaterialList();//物料列表
},
methods: { methods: {
checkPermission, checkPermission,
//产品列表 //产品列表

View File

@ -7,7 +7,8 @@
">子工序列表</span> ">子工序列表</span>
</div> </div>
<el-button type="primary" icon="el-icon-plus" @click="handleCreateStep" <el-button type="primary" icon="el-icon-plus" @click="handleCreateStep"
>新增子工序</el-button> >新增子工序
</el-button>
<el-table <el-table
v-loading="listLoading" v-loading="listLoading"
:data="stepList" :data="stepList"
@ -27,18 +28,19 @@
</el-table-column> </el-table-column>
<el-table-column label="相关设备"> <el-table-column label="相关设备">
<template slot-scope="scope" v-if="scope.row.equipments"> <template slot-scope="scope" v-if="scope.row.equipments">
<el-tag v-for="item in scope.row.equipments_" <el-tag
v-for="item in scope.row.equipments_"
:key="item.number" :key="item.number"
:label="item.name" :label="item.name"
:value="item.number">{{item.name}}</el-tag> :value="item.number"
>
{{item.name}}
</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="子工序类型"> <el-table-column label="子工序类型">
<template slot-scope="scope">{{ type_[scope.row.type] }}</template> <template slot-scope="scope">{{ type_[scope.row.type] }}</template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
align="center" align="center"
label="操作" label="操作"
@ -46,17 +48,17 @@
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
v-if="checkPermission(['step_update'])"
type="primary" type="primary"
@click="handleEditStep(scope)" @click="handleEditStep(scope)"
>编辑</el-link
> >
编辑
</el-link>
<el-link <el-link
v-if="checkPermission(['step_delete'])"
type="danger" type="danger"
@click="handleDeleteStep(scope)" @click="handleDeleteStep(scope)"
>删除</el-link
> >
删除
</el-link>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -79,34 +81,30 @@
<el-input v-model="step.number" placeholder="工序编号"/> <el-input v-model="step.number" placeholder="工序编号"/>
</el-form-item> </el-form-item>
<el-form-item label="工序设备" prop="equipments"> <el-form-item label="工序设备" prop="equipments">
<el-select style="width: 100%" multiple v-model="step.equipments" placeholder="请选择"> <el-select style="width: 100%" multiple v-model="step.equipments" placeholder="请选择">
<el-option <el-option
v-for="item in options" v-for="item in options"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
:value="item.value"> :value="item.value"
>
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="指导书内容" prop="instruction_content"> <el-form-item label="指导书内容" prop="instruction_content">
<el-input type="textarea" :rows="3" v-model="step.instruction_content" placeholder="指导书内容"/> <el-input type="textarea" :rows="3" v-model="step.instruction_content" placeholder="指导书内容"/>
</el-form-item> </el-form-item>
<el-form-item label="子工序类型" prop="type"> <el-form-item label="子工序类型" prop="type">
<el-select style="width: 100%" v-model="step.type" placeholder="请选择"> <el-select style="width: 100%" v-model="step.type" placeholder="请选择">
<el-option <el-option
v-for="item in typeoption" v-for="item in typeoption"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
:value="item.value"> :value="item.value"
>
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div style="text-align: right"> <div style="text-align: right">
<el-button type="danger" @click="dialogVisibles = false">取消</el-button> <el-button type="danger" @click="dialogVisibles = false">取消</el-button>
@ -123,8 +121,13 @@
font-weight: 700; font-weight: 700;
">过程记录表</span> ">过程记录表</span>
</div> </div>
<el-button type="primary" icon="el-icon-plus" @click="handleCreate" <el-button
>新增</el-button> type="primary"
icon="el-icon-plus"
@click="handleCreate"
>
新增
</el-button>
<el-table <el-table
:data="recordformList.results" :data="recordformList.results"
border border
@ -136,8 +139,9 @@
@current-change="handleCurrentChange" @current-change="handleCurrentChange"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="名称"> <el-table-column label="名称" prop="name"></el-table-column>
<template slot-scope="scope">{{ scope.row.name }}</template> <el-table-column label="关联产品">
<template slot-scope="scope" v-if="scope.row.material_">{{ scope.row.material_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="状态"> <el-table-column label="状态">
<template slot-scope="scope"> <template slot-scope="scope">
@ -154,20 +158,20 @@
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
v-if="checkPermission(['material_update'])"
type="primary" type="primary"
@click="handleLook(scope)" @click="handleLook(scope)"
>查看</el-link> >查看
</el-link>
<el-link <el-link
v-if="checkPermission(['material_update'])"
type="primary" type="primary"
@click="handleEdit(scope)" @click="handleEdit(scope)"
>编辑</el-link> >编辑
</el-link>
<el-link <el-link
v-if="checkPermission(['material_delete'])"
type="danger" type="danger"
@click="handleDelete(scope)" @click="handleDelete(scope)"
>删除</el-link> >删除
</el-link>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -182,31 +186,54 @@
label-width="80px" label-width="80px"
label-position="right" label-position="right"
> >
<el-form-item label="表格名称" prop="name"> <el-form-item label="表格名称" prop="name">
<el-input v-model="recordform.name" placeholder="表格名称"/> <el-input v-model="recordform.name" placeholder="表格名称"/>
</el-form-item> </el-form-item>
<el-form-item label="文件号" prop="number"> <el-form-item label="文件号" prop="number">
<el-input v-model="recordform.number" placeholder="文件号"/> <el-input v-model="recordform.number" placeholder="文件号"/>
</el-form-item> </el-form-item>
<el-form-item label="状态"> <el-form-item label="状态">
<el-switch v-model="recordform.enabled"></el-switch> <el-switch v-model="recordform.enabled"></el-switch>
</el-form-item> </el-form-item>
<el-form-item label="表格类型" prop="type"> <el-form-item label="表格类型" prop="type">
<el-select style="width: 100%" v-model="recordform.type" placeholder="请选择"> <el-select style="width: 100%" v-model="recordform.type" placeholder="请选择">
<el-option <el-option
v-for="item in typeoptions" v-for="item in typeoptions"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
:value="item.value"> :value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="引用表单" v-if="dialogType === 'new'">
<el-select
v-model="recordform.form"
style="width: 100%"
clearable
filterable
placeholder="请选择"
>
<el-option
v-for="item in formList"
:key="item.id"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="关联产品">
<el-select style="width: 100%" v-model="recordform.material" clearable placeholder="请选择">
<el-option
v-for="item in productOptions"
:key="item.id"
:label="item.name"
:value="item.id"
>
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div style="text-align: right"> <div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button> <el-button type="danger" @click="dialogVisible = false">取消</el-button>
@ -214,70 +241,86 @@
</div> </div>
</el-dialog> </el-dialog>
<el-dialog <el-dialog
class="bigDialog"
:model="tableForm" :model="tableForm"
:close-on-click-modal="false" :close-on-click-modal="false"
:visible.sync="dialogVisibleForm" :visible.sync="dialogVisibleForm"
:title="tableForm.name"> :title="tableForm.name"
>
<el-form <el-form
label-width="80px" label-width="200px"
label-position="right" label-position="right"
> >
<el-row v-for="(item,$index) in fieldList.results" :key="$index"> <el-row style="box-sizing: border-box;padding-right: 50px">
<el-col v-for="(item,$index) in dialogFieldList" :key="$index" :span="12">
<el-form-item v-if="item.field_type==='string'" :label="item.field_name"> <el-form-item v-if="item.field_type==='string'" :label="item.field_name">
<el-input placeholder="请输入" v-model="item.sort"/> <el-input placeholder="请输入" v-model="item.low_limit"/>
<span v-if="item.help_text!==''&&item.help_text">{{item.help_text}}</span>
</el-form-item> </el-form-item>
<el-form-item v-else-if="item.field_type==='int'" :label="item.field_name"> <el-form-item v-else-if="item.field_type==='int'" :label="item.field_name">
<el-input type="number" placeholder="请输入" v-model="item.sort"/> <el-input type="number" placeholder="请输入" v-model="item.low_limit"/>
<span v-if="item.help_text!==''&&item.help_text">{{item.help_text}}</span>
</el-form-item> </el-form-item>
<el-form-item v-else-if="item.field_type==='float'" :label="item.field_name"> <el-form-item v-else-if="item.field_type==='float'" :label="item.field_name">
<el-input type="number" placeholder="请输入" v-model="item.sort"/> <el-input type="number" placeholder="请输入" v-model="item.low_limit"/>
<span v-if="item.help_text!==''&&item.help_text">{{item.help_text}}</span>
</el-form-item> </el-form-item>
<el-form-item v-else-if="item.field_type==='date'" :label="item.field_name"> <el-form-item v-else-if="item.field_type==='date'" :label="item.field_name">
<el-date-picker <el-date-picker
v-model="item.create_time" v-model="item.low_limit"
type="date" type="date"
placeholder="选择日期" placeholder="选择日期"
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"
style="width:100%" style="width:100%"
> >
</el-date-picker> </el-date-picker>
<span v-if="item.help_text!==''&&item.help_text">{{item.help_text}}</span>
</el-form-item> </el-form-item>
<el-form-item v-else-if="item.field_type==='datetime'" :label="item.field_name"> <el-form-item v-else-if="item.field_type==='datetime'" :label="item.field_name">
<el-date-picker <el-date-picker
v-model="item.create_time" v-model="item.low_limit"
type="datetime" type="datetime"
placeholder="选择日期" placeholder="选择日期"
value-format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
style="width:100%" style="width:100%"
> >
</el-date-picker> </el-date-picker>
<span v-if="item.help_text!==''&&item.help_text">{{item.help_text}}</span>
</el-form-item> </el-form-item>
<el-form-item v-else-if="item.field_type==='select'" :label="item.field_name"> <el-form-item v-else-if="item.field_type==='select'" :label="item.field_name">
<el-select style="width: 100%" v-model="item.sort" placeholder="请选择"> <el-select style="width: 100%" placeholder="请选择">
<el-option <el-option
v-model="item.low_limit"
v-for="item1 in item.field_choice" v-for="item1 in item.field_choice"
:key="item1" :key="item1"
:label="item1" :label="item1"
:value="item1"> :value="item1">
</el-option> </el-option>
</el-select> </el-select>
<span v-if="item.help_text!==''&&item.help_text">{{item.help_text}}</span>
</el-form-item> </el-form-item>
<el-form-item v-else-if="item.field_type==='selects'" :label="item.field_name"> <el-form-item v-else-if="item.field_type==='selects'" :label="item.field_name">
<el-select style="width: 100%" v-model="optio" multiple placeholder="请选择"> <el-select style="width: 100%" multiple placeholder="请选择">
<el-option <el-option
v-model="item.low_limit"
v-for="item1 in item.field_choice" v-for="item1 in item.field_choice"
:key="item1" :key="item1"
:label="item1" :label="item1"
:value="item1"> :value="item1">
</el-option> </el-option>
</el-select> </el-select>
<span v-if="item.help_text!==''&&item.help_text">{{item.help_text}}</span>
</el-form-item> </el-form-item>
</el-col>
</el-row>
<el-row style="box-sizing: border-box;padding-right: 50px">
<el-col v-for="(item,$index) in dialogFieldList" :key="$index" :span="12">
<el-form-item v-if="item.field_type==='draw'" :label="item.field_name">
<img style="width: 500px;" :src="item.draw_template" alt="tupian">
</el-form-item>
</el-col>
</el-row> </el-row>
</el-form> </el-form>
<!--<div style="text-align: right">-->
<!--<el-button type="danger">取消</el-button>-->
<!--<el-button type="primary">确认</el-button>-->
<!--</div>-->
</el-dialog> </el-dialog>
</el-card> </el-card>
</el-col> </el-col>
@ -288,10 +331,14 @@
font-weight: 700; font-weight: 700;
">记录字段</span> ">记录字段</span>
</div> </div>
<el-button type="primary" icon="el-icon-plus" @click="handlefieldCreate" <el-button
>新增</el-button> type="primary"
icon="el-icon-plus"
@click="handlefieldCreate"
>
新增
</el-button>
<el-table <el-table
:data="fieldList.results" :data="fieldList.results"
border border
fit fit
@ -299,49 +346,44 @@
highlight-current-row highlight-current-row
height="100" height="100"
v-el-height-adaptive-table="{bottomOffset: 50}" v-el-height-adaptive-table="{bottomOffset: 50}"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="字段类型"> <el-table-column label="字段类型">
<template slot-scope="scope">{{ options_[scope.row.field_type] }}</template> <template slot-scope="scope">{{ options_[scope.row.field_type] }}</template>
</el-table-column> </el-table-column>
<el-table-column label="字段名称"> <el-table-column label="字段名称">
<template slot-scope="scope">{{ scope.row.field_name }}</template> <template slot-scope="scope">{{ scope.row.field_name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="字段标识"> <el-table-column label="字段标识">
<template slot-scope="scope">{{ scope.row.field_key }}</template> <template slot-scope="scope">{{ scope.row.field_key }}</template>
</el-table-column> </el-table-column>
<el-table-column label="选项显示名"> <el-table-column label="选项显示名">
<template slot-scope="scope">{{ scope.row.field_choice }}</template> <template slot-scope="scope">{{ scope.row.field_choice }}</template>
</el-table-column> </el-table-column>
<el-table-column label="字段说明">
<template slot-scope="scope">{{ scope.row.help_text }}</template>
</el-table-column>
<el-table-column <el-table-column
align="center" align="center"
label="操作" label="操作"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
v-if="checkPermission(['material_update'])" v-if="checkPermission(['material_update'])"
type="primary" type="primary"
@click="handlefieldEdit(scope)" @click="handlefieldEdit(scope)"
>编辑</el-link
> >
编辑
</el-link>
<el-link <el-link
v-if="checkPermission(['material_delete'])" v-if="checkPermission(['material_delete'])"
type="danger" type="danger"
@click="handlefieldDelete(scope)" @click="handlefieldDelete(scope)"
>删除</el-link
> >
删除
</el-link>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination <pagination
v-show="fieldList.count > 0" v-show="fieldList.count > 0"
@ -350,7 +392,8 @@
:limit.sync="listQueryfield.page_size" :limit.sync="listQueryfield.page_size"
@pagination="fieldLists" @pagination="fieldLists"
/> />
<el-dialog :visible.sync="dialogVisible1" :close-on-click-modal="false" :title="dialogType1 === 'edit' ? '编辑表格字段' : '新增表格字段'"> <el-dialog :visible.sync="dialogVisible1" :close-on-click-modal="false"
:title="dialogType1 === 'edit' ? '编辑表格字段' : '新增表格字段'">
<el-form ref="Form" :model="field" label-width="80px" label-position="right"> <el-form ref="Form" :model="field" label-width="80px" label-position="right">
<el-form-item label="字段类型" prop="field_type"> <el-form-item label="字段类型" prop="field_type">
<el-select style="width: 100%" v-model="field.field_type" placeholder="请选择"> <el-select style="width: 100%" v-model="field.field_type" placeholder="请选择">
@ -363,12 +406,22 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="字段标识" prop="field_key"> <el-form-item label="字段标识" prop="field_key">
<el-input v-model="field.field_key" placeholder="字段标识" onkeyup="value=value.replace(/[^A-Za-z_\/]/ig,'')"/> <el-input
v-model="field.field_key"
placeholder="字段标识"
@input="checkValue"
/>
</el-form-item> </el-form-item>
<el-form-item label="字段名称" prop="field_name"> <el-form-item label="字段名称" prop="field_name">
<el-input v-model="field.field_name" placeholder="字段名称"/> <el-input v-model="field.field_name" placeholder="字段名称"/>
</el-form-item> </el-form-item>
<el-form-item label="选项" v-show="field.field_type=='radio'||field.field_type=='checkbox'||field.field_type=='select'||field.field_type=='selects'"> <el-form-item label="字段说明">
<el-input v-model="field.help_text" placeholder="字段说明"/>
</el-form-item>
<el-form-item
v-show="field.field_type==='radio'||field.field_type==='checkbox'||field.field_type==='select'||field.field_type==='selects'"
label="选项"
>
<el-button @click.prevent="addDomain" style="border: none;"> <el-button @click.prevent="addDomain" style="border: none;">
<i class="el-icon-circle-plus-outline"></i> <i class="el-icon-circle-plus-outline"></i>
<span style="font-size:14px;">添加</span> <span style="font-size:14px;">添加</span>
@ -378,10 +431,25 @@
<el-input v-model="field_choice[$index]" auto-complete="off"></el-input> <el-input v-model="field_choice[$index]" auto-complete="off"></el-input>
</el-col> </el-col>
<el-col :span="3" style="text-align: center" v-if="$index!==0"> <el-col :span="3" style="text-align: center" v-if="$index!==0">
<i class="el-icon-remove-outline" @click.prevent="removeDomain($index,'1')" style="color: red;font-size: 16px;"></i> <i class="el-icon-remove-outline" @click.prevent="removeDomain($index,'1')"
style="color: red;font-size: 16px;"></i>
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="模板图片" v-if="field.field_type === 'draw'">
<el-upload
class="avatar-uploader"
:action="upUrl"
accept="image/jpeg, image/gif, image/png, image/bmp"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
:headers="upHeaders"
>
<img v-if="field.draw_template" :src="field.draw_template" class="avatar"/>
<i v-else class="el-icon-plus avatar-uploader-icon"/>
</el-upload>
</el-form-item>
<el-form-item label="排序" prop="sort"> <el-form-item label="排序" prop="sort">
<el-input-number v-model="field.sort" :min="1" placeholder="排序"></el-input-number> <el-input-number v-model="field.sort" :min="1" placeholder="排序"></el-input-number>
</el-form-item> </el-form-item>
@ -399,12 +467,20 @@
</template> </template>
<script> <script>
import { getStepLists, createStep,updateStep,deleteStep } from "@/api/mtm"; import {getStepLists, createStep, updateStep, deleteStep,getMaterialList} from "@/api/mtm";
import checkPermission from "@/utils/permission"; import checkPermission from "@/utils/permission";
import {getEquipmentAll} from "@/api/equipment"; import {getEquipmentAll} from "@/api/equipment";
import {upUrl, upHeaders} from "@/api/file"; import {upUrl, upHeaders} from "@/api/file";
import { getStep,getrecordformList,createrecordform,updaterecordform,deleterecordform,getrffieldList,createrffield,updaterffield, import {
deleterffield} from "@/api/mtm"; getrecordformList,
createrecordform,
updaterecordform,
deleterecordform,
getrffieldList,
createrffield,
updaterffield,
deleterffield
} from "@/api/mtm";
import vueJsonEditor from 'vue-json-editor' import vueJsonEditor from 'vue-json-editor'
import {genTree} from "@/utils"; import {genTree} from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
@ -417,15 +493,16 @@
const defaultrecordform = { const defaultrecordform = {
enabled: true enabled: true
}; };
const defaultfield = { const defaultfield = {};
const defaultfield1 = {field_type: '', field_key: '', field_name: '', sort: '', field_choice: [""],};
};
export default { export default {
components: {Pagination, vueJsonEditor}, components: {Pagination, vueJsonEditor},
data() { data() {
return { return {
step: defaultstep, step: defaultstep,
stepList: [], stepList: [],
dialogFieldList: [],
productOptions: [],
upHeaders: upHeaders(), upHeaders: upHeaders(),
upUrl: upUrl(), upUrl: upUrl(),
fileList: { fileList: {
@ -441,6 +518,7 @@
field_name: '', field_name: '',
sort: '', sort: '',
field_choice: [""], field_choice: [""],
draw_template:''
}, },
field_choice: [''], field_choice: [''],
options: [], options: [],
@ -485,6 +563,7 @@
'datetime': '日期时间', 'datetime': '日期时间',
'select': '单选', 'select': '单选',
'selects': '多选', 'selects': '多选',
'draw': '绘图模板',
}, },
typeoption: [{ typeoption: [{
value: 1, value: 1,
@ -529,10 +608,15 @@
{ {
value: 'selects', value: 'selects',
label: '多选' label: '多选'
},
{
value: 'draw',
label: '绘图模板'
} }
], ],
formList:[],
typeoptions: [{ typeoptions: [{
value: 1, value: 10,
label: '生产记录' label: '生产记录'
}], }],
}; };
@ -543,9 +627,23 @@
this.step.process = this.$route.params.id; this.step.process = this.$route.params.id;
this.getList(); this.getList();
this.getequipments() this.getequipments()
},
mounted(){
this.step.process = this.$route.params.id;
this.getProductList();
this.getFormList();
}, },
methods: { methods: {
checkValue() {
this.field.field_key = this.field.field_key.replace(/[^0-9a-zA-Z]/g, '');
},
getProductList(){
getMaterialList({page:0,type:1}).then((response) => {
if (response.data) {
this.productOptions = response.data;
}
})
},
//添加字段选项 //添加字段选项
addDomain(){ addDomain(){
this.field_choice.push('') this.field_choice.push('')
@ -555,12 +653,15 @@
this.field_choice.splice(index, 1) this.field_choice.splice(index, 1)
}, },
handleLook(scope) { handleLook(scope) {
debugger;
console.log(scope);
this.dialogVisibleForm = true; this.dialogVisibleForm = true;
this.tableForm = Object.assign({}, scope.row); // copy obj this.dialogFieldList = [];
this.tableForm = Object.assign({}, scope.row);
this.formID = this.tableForm.id; this.formID = this.tableForm.id;
this.fieldLists(); getrffieldList({page:0,form:this.formID}).then((response) => {
if (response.data) {
this.dialogFieldList = response.data;
}
});
}, },
checkPermission, checkPermission,
//子工序列表 //子工序列表
@ -595,9 +696,6 @@
this.step.instruction = null; this.step.instruction = null;
}, },
handleFilter() { handleFilter() {
this.listQuery.page = 1; this.listQuery.page = 1;
this.getList(); this.getList();
@ -618,8 +716,8 @@
this.$refs["Form"].clearValidate(); this.$refs["Form"].clearValidate();
}); });
}, },
rowClick(row) {
rowClick(row) {
this.stepid = row.id; this.stepid = row.id;
this.recordformLists(); this.recordformLists();
}, },
@ -633,6 +731,7 @@
this.$refs["Form"].clearValidate(); this.$refs["Form"].clearValidate();
}); });
}, },
handleDeleteStep(scope) { handleDeleteStep(scope) {
this.$confirm("确认删除?", "警告", { this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认", confirmButtonText: "确认",
@ -663,7 +762,6 @@
} }
}); });
} else { } else {
console.log(this.step)
createStep(this.step).then((res) => { createStep(this.step).then((res) => {
if (res.code >= 200) { if (res.code >= 200) {
this.getList(); this.getList();
@ -677,50 +775,74 @@
} }
}); });
}, },
handleCurrentChange(row) { handleCurrentChange(row) {
this.formID = row.id; this.formID = row.id;
this.fieldLists(); this.fieldLists();
}, },
recordformLists()
{ recordformLists() {
this.listQueryrecordform.step = this.stepid; this.listQueryrecordform.step = this.stepid;
this.listQueryrecordform.type = 10; this.listQueryrecordform.type = 10;
getrecordformList(this.listQueryrecordform).then((response) => { getrecordformList(this.listQueryrecordform).then((response) => {
if (response.data) { if (response.data) {
this.recordformList = response.data; this.recordformList = response.data;
} }
}); });
}, },
fieldLists() getFormList(){
{ getrecordformList({page:0,type:10}).then((response) => {
this.listQueryfield.form=this.formID if (response.data) {
this.formList = response.data;
}
});
},
fieldLists() {
this.listQueryfield.form = this.formID;
getrffieldList(this.listQueryfield).then((response) => { getrffieldList(this.listQueryfield).then((response) => {
if (response.data) { if (response.data) {
this.fieldList = response.data; this.fieldList = response.data;
debugger;
console.log(this.fieldList)
} }
}); });
}, },
//新增记录表 //新增记录表
handleCreate() { handleCreate() {
if(this.stepid!==''&&this.stepid!==null&&this.stepid!==undefined){
this.recordform = Object.assign({}, defaultrecordform); this.recordform = Object.assign({}, defaultrecordform);
this.dialogType = "new"; this.dialogType = "new";
this.dialogVisible = true; this.dialogVisible = true;
this.$nextTick(() => { this.$nextTick(() => {
this.$refs["Forms"].clearValidate(); this.$refs["Forms"].clearValidate();
}); });
}else{
this.$confirm("请选择子工序", "警告", {
confirmButtonText: "确认",
type: "error",
}) .then(async () => {
})
.catch(() => {
});
}
},
handleAvatarSuccess(res, file) {
debugger;
console.log(res)
this.field.draw_template = res.data.path;
},
beforeAvatarUpload(file) {
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error("上传头像图片大小不能超过 2MB!");
}
return isLt2M;
}, },
//新增字段 //新增字段
handlefieldCreate() { handlefieldCreate() {
this.field_choice = ['']; this.field_choice = [''];
this.field = Object.assign({}, defaultfield); this.field = Object.assign({}, defaultfield1);
this.dialogType1 = "new"; this.dialogType1 = "new";
this.dialogVisible1 = true; this.dialogVisible1 = true;
this.$nextTick(() => { this.$nextTick(() => {
this.$refs["Form"].clearValidate(); this.$refs["Form"].clearValidate();
}); });
@ -750,7 +872,7 @@
}) })
.then(async () => { .then(async () => {
await deleterecordform(scope.row.id); await deleterecordform(scope.row.id);
this.recordformLists() this.recordformLists();
this.$message.success("成功"); this.$message.success("成功");
}) })
.catch((err) => { .catch((err) => {
@ -765,7 +887,7 @@
}) })
.then(async () => { .then(async () => {
await deleterffield(scope.row.id); await deleterffield(scope.row.id);
this.fieldLists() this.fieldLists();
this.$message.success("成功"); this.$message.success("成功");
}) })
.catch((err) => { .catch((err) => {
@ -777,21 +899,19 @@
if (valid) { if (valid) {
const isEdit = this.dialogType === "edit"; const isEdit = this.dialogType === "edit";
if (isEdit) { if (isEdit) {
this.recordform.step=this.stepid this.recordform.step = this.stepid;
updaterecordform(this.recordform.id, this.recordform).then((res) => { updaterecordform(this.recordform.id, this.recordform).then((res) => {
if (res.code >= 200) { if (res.code >= 200) {
this.recordformLists() this.recordformLists();
this.dialogVisible = false; this.dialogVisible = false;
this.$message.success("成功"); this.$message.success("成功");
} }
}); });
} else { } else {
this.recordform.step=this.stepid this.recordform.step = this.stepid;
createrecordform(this.recordform).then((res) => { createrecordform(this.recordform).then((res) => {
if (res.code >= 200) { if (res.code >= 200) {
this.recordformLists() this.recordformLists();
this.dialogVisible = false; this.dialogVisible = false;
this.$message.success("成功"); this.$message.success("成功");
} }
@ -811,7 +931,7 @@
this.field.field_choice = this.field_choice; this.field.field_choice = this.field_choice;
updaterffield(this.field.id, this.field).then((res) => { updaterffield(this.field.id, this.field).then((res) => {
if (res.code >= 200) { if (res.code >= 200) {
this.fieldLists() this.fieldLists();
this.dialogVisible1 = false; this.dialogVisible1 = false;
this.$message.success("成功"); this.$message.success("成功");
} }
@ -821,7 +941,7 @@
this.field.field_choice = this.field_choice; this.field.field_choice = this.field_choice;
createrffield(this.field).then((res) => { createrffield(this.field).then((res) => {
if (res.code >= 200) { if (res.code >= 200) {
this.fieldLists() this.fieldLists();
this.dialogVisible1 = false; this.dialogVisible1 = false;
this.$message.success("成功"); this.$message.success("成功");
} }

View File

@ -190,8 +190,7 @@
}, { }, {
value: '', value: '',
label: '' label: ''
}, }, {
{
value: '', value: '',
label: '' label: ''
}, { }, {
@ -200,6 +199,27 @@
}, { }, {
value: '', value: '',
label: '' label: ''
}, {
value: 'g',
label: 'g'
}, {
value: 'kg',
label: 'kg'
}, {
value: '',
label: ''
}, {
value: '',
label: ''
}, {
value: '',
label: ''
}, {
value: '',
label: ''
},{
value: '',
label: ''
}, },
], ],
listQuery: { listQuery: {
@ -241,7 +261,21 @@
}, },
//检查表 //检查表
handlebind(scope) { handlebind(scope) {
this.$router.push({name: "MaterialDO", params: {id: scope.row.id},}) let materialItem = sessionStorage.getItem('materialItem');
let materialType = sessionStorage.getItem('materialType');
if(materialItem){
sessionStorage.removeItem('materialItem');
sessionStorage.setItem('materialItem',JSON.stringify(scope.row));
}else{
sessionStorage.setItem('materialItem',JSON.stringify(scope.row));
}
if(materialType){
sessionStorage.removeItem('materialType');
sessionStorage.setItem('materialType','20,50');
}else{
sessionStorage.setItem('materialType','20,50');
}
this.$router.push({name: "MaterialDO", params: {id: scope.row.id}})
}, },
handleFilter() { handleFilter() {
this.listQuery.page = 1; this.listQuery.page = 1;

View File

@ -333,9 +333,9 @@ export default {
this.user.avatar = res.data.path; this.user.avatar = res.data.path;
}, },
beforeAvatarUpload(file) { beforeAvatarUpload(file) {
const isLt2M = file.size / 1024 / 1024 < 2; const isLt2M = file.size / 1024 / 1024 < 10;
if (!isLt2M) { if (!isLt2M) {
this.$message.error("上传头像图片大小不能超过 2MB!"); this.$message.error("上传头像图片大小不能超过 10MB!");
} }
return isLt2M; return isLt2M;
}, },
@ -344,9 +344,9 @@ export default {
return data.label.indexOf(value) !== -1; return data.label.indexOf(value) !== -1;
}, },
beforeUpload(file) { beforeUpload(file) {
const isLt1M = file.size / 1024 / 1024 < 1; const isLt1M = file.size / 1024 / 1024 < 10;
if (!isLt1M) { if (!isLt1M) {
this.$message.error("上传头像图片大小不能超过 1MB!"); this.$message.error("上传头像图片大小不能超过 10MB!");
} }
return isLt1M; return isLt1M;
}, },

View File

@ -33,7 +33,7 @@
fit fit
stripe stripe
style="width: 100%" style="width: 100%"
height="300" :height="domHeight"
@row-click="tableRowClick" @row-click="tableRowClick"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
@ -96,7 +96,7 @@
@pagination="getplanList" @pagination="getplanList"
/> />
</el-card> </el-card>
<el-card class="box-card"> <el-card class="box-card" id="ganttCard">
<div style="height: 40px;line-height: 40px;background: #F5F7FA;padding-left: 20px;">甘特图</div> <div style="height: 40px;line-height: 40px;background: #F5F7FA;padding-left: 20px;">甘特图</div>
<gantt <gantt
v-if="proList.length>0" v-if="proList.length>0"
@ -116,6 +116,7 @@
components: {Pagination, gantt}, components: {Pagination, gantt},
data() { data() {
return { return {
domHeight:null,
productionplanList: { productionplanList: {
count: 0, count: 0,
}, },
@ -279,6 +280,11 @@
this.$router.push({name: "plandetails", params: {id: scope.row.id}}); this.$router.push({name: "plandetails", params: {id: scope.row.id}});
}, },
}, },
mounted() {
let hei = document.getElementsByClassName('app-main')[0].clientHeight;//
// let h = document.getElementById('ganttCard').clientHeight;//
this.domHeight = hei - 460;
}
}; };
</script> </script>

View File

@ -29,49 +29,50 @@
</el-button> </el-button>
<el-table <el-table
:data="productionplanList.results" :data="productionplanList.results"
id="productionPlan"
border border
fit fit
stripe stripe
style="width: 100%" style="width: 100%"
height="300" :height="domHeight"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="任务编号" prop="number" width="110"> <el-table-column label="任务编号" prop="number" min-width="110">
</el-table-column> </el-table-column>
<el-table-column label="订单编号" width="110"> <el-table-column label="订单编号" min-width="110">
<template slot-scope="scope">{{ scope.row.order_.number }}</template> <template slot-scope="scope">{{ scope.row.order_.number }}</template>
</el-table-column> </el-table-column>
<el-table-column label="合同编号" width="110"> <el-table-column label="合同编号" min-width="110">
<template slot-scope="scope" v-if="scope.row.order_.contract_"> <template slot-scope="scope" v-if="scope.row.order_.contract_">
<span v-if="scope.row.order_.contract_">{{scope.row.order_.contract_.number }}</span> <span v-if="scope.row.order_.contract_">{{scope.row.order_.contract_.number }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="产品名称" width="150" show-overflow-tooltip> <el-table-column label="产品名称" min-width="150" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.product_.name }}</template> <template slot-scope="scope">{{ scope.row.product_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="产品型号" width="110"> <el-table-column label="产品型号" min-width="110">
<template slot-scope="scope"> <template slot-scope="scope">
{{scope.row.product_.specification}} {{scope.row.product_.specification}}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="产品单位" width="110"> <el-table-column label="产品单位" min-width="110">
<template slot-scope="scope">{{ scope.row.product_.unit }}</template> <template slot-scope="scope">{{ scope.row.product_.unit }}</template>
</el-table-column> </el-table-column>
<el-table-column label="生产数量" prop="count" width="110"> <el-table-column label="生产数量" prop="count" min-width="110">
</el-table-column> </el-table-column>
<el-table-column label="状态" width="110"> <el-table-column label="状态" min-width="110">
<template slot-scope="scope">{{ state_[scope.row.state] }}</template> <template slot-scope="scope">{{ state_[scope.row.state] }}</template>
</el-table-column> </el-table-column>
<el-table-column label="计划开工时间" prop="start_date" width="110"> <el-table-column label="计划开工时间" prop="start_date" min-width="110">
</el-table-column> </el-table-column>
<el-table-column label="计划完工时间" prop="end_date" width="110"> <el-table-column label="计划完工时间" prop="end_date" min-width="110">
</el-table-column> </el-table-column>
<el-table-column label="交货日期" width="110"> <el-table-column label="交货日期" min-width="110">
<template slot-scope="scope"> <template slot-scope="scope">
{{scope.row.order_.delivery_date}} {{scope.row.order_.delivery_date}}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="是否生成子计划" width="120"> <el-table-column label="是否生成子计划" min-width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.is_planed == false"></el-tag> <el-tag v-if="scope.row.is_planed == false"></el-tag>
<el-tag v-if="scope.row.is_planed == true"></el-tag> <el-tag v-if="scope.row.is_planed == true"></el-tag>
@ -87,7 +88,7 @@
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
v-if="checkPermission(['plan_toggle'])&&scope.row.state !== 70" v-if="checkPermission(['plan_toggle'])&&scope.row.state===40"
type="warning" type="warning"
@click="handlestatesuspended(scope)" @click="handlestatesuspended(scope)"
> >
@ -100,6 +101,7 @@
> >
启用 启用
</el-link> </el-link>
<!--暂停时才能终止-->
<el-link <el-link
v-if="checkPermission(['plan_stop'])&&scope.row.state === 70" v-if="checkPermission(['plan_stop'])&&scope.row.state === 70"
type="danger" type="danger"
@ -108,14 +110,13 @@
终止 终止
</el-link> </el-link>
<el-link <el-link
v-if="checkPermission(['plan_subcreate'])&&scope.row.is_planed"
type="primary" type="primary"
@click="handleselectplan(scope)" @click="handleselectplan(scope)"
> >
查看子计划 查看
</el-link> </el-link>
<el-link <el-link
v-if="checkPermission(['plan_subcreate'])&&!scope.row.is_planed" v-if="checkPermission(['gen_subplan'])&&!scope.row.is_planed"
type="primary" type="primary"
@click="handleWork(scope)" @click="handleWork(scope)"
> >
@ -141,11 +142,12 @@
<el-tab-pane label="订单排产" name="订单排产"> <el-tab-pane label="订单排产" name="订单排产">
<el-table <el-table
:data="orderList.results" :data="orderList.results"
id="orderList"
border border
fit fit
stripe stripe
style="width: 100%" style="width: 100%"
height="250" :height="domHeight"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="订单编号" width="110"> <el-table-column label="订单编号" width="110">
@ -235,6 +237,9 @@
> >
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
<el-form-item label="任务编号" prop="number">
<el-input v-model="orderplan.number" @input="checkValue" placeholder="任务编号"/>
</el-form-item>
</el-form> </el-form>
<div style="text-align: right"> <div style="text-align: right">
<el-button <el-button
@ -273,11 +278,18 @@
import {genTree} from "@/utils"; import {genTree} from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaulteorderplan = {}; const defaulteorderplan = {
order:'',
number:'',
count:'',
end_date:'',
start_date:'',
};
export default { export default {
components: {Pagination, gantt}, components: {Pagination, gantt},
data() { data() {
return { return {
domHeight:null,
orderplan: defaulteorderplan, orderplan: defaulteorderplan,
orderList: { orderList: {
count: 0, count: 0,
@ -311,7 +323,7 @@
dialogType: "new", dialogType: "new",
activeName: "订单排产", activeName: "订单排产",
rule1: { rule1: {
number: [{required: true, message: "请输入", trigger: "blur"}], number: [{required: true, message: "请输入任务编号", trigger: "blur"}],
}, },
proList: [], proList: [],
}; };
@ -324,7 +336,9 @@
}, },
methods: { methods: {
checkPermission, checkPermission,
checkValue() {
this.orderplan.number = this.orderplan.number.replace(/[^0-9a-zA-Z]/g, '');
},
//订单列表 //订单列表
getorderList() { getorderList() {
this.listLoading = true; this.listLoading = true;
@ -507,6 +521,12 @@
this.$router.push({name: "work", params: {id: scope.row.id}}); this.$router.push({name: "work", params: {id: scope.row.id}});
}, },
}, },
mounted() {
let hei = document.getElementsByClassName('app-main')[0].clientHeight;//
let domHeight = this.domHeight = (hei - 205) / 2;
document.getElementById('orderList').style.height = domHeight + 'px';
document.getElementById('productionPlan').style.height = domHeight + 'px';
}
}; };
</script> </script>

View File

@ -30,15 +30,10 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="产品状态"> <el-table-column label="产品状态">
<template slot-scope="scope">{{ <template slot-scope="scope">{{actstate_[scope.row.act_state]}}</template>
actstate_[scope.row.act_state]
}}
</template>
</el-table-column> </el-table-column>
<el-table-column label="生产状态"> <el-table-column label="生产状态">
<template slot-scope="scope"> <template slot-scope="scope">{{scope.row.step_.name}}</template>
{{scope.row.step_.name}}
</template>
</el-table-column> </el-table-column>
<el-table-column label="最后检验结果"> <el-table-column label="最后检验结果">
<template slot-scope="scope"> <template slot-scope="scope">
@ -58,7 +53,6 @@
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
v-if="checkPermission(['material_delete'])"
type="primary" type="primary"
@click="handleoption(scope)" @click="handleoption(scope)"
>生成流程卡 >生成流程卡
@ -106,7 +100,7 @@
<el-col v-for="item in fieldList" :key="item.id" :span="24"> <el-col v-for="item in fieldList" :key="item.id" :span="24">
<div class="items" v-if="item.field_type==='draw'" style="height: 400px"> <div class="items" v-if="item.field_type==='draw'" style="height: 400px">
<span class="itemLabel">{{item.field_name}}</span> <span class="itemLabel">{{item.field_name}}</span>
<img style="width: 45%;vertical-align: text-top;" :src="'http://49.232.14.174:2222'+item.field_value"/> <img style="width: 45%;vertical-align: text-top;" :src="item.field_value"/>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>

View File

@ -21,66 +21,38 @@
stripe stripe
highlight-current-row highlight-current-row
height="100" height="100"
v-el-height-adaptive-table="{ bottomOffset: 25 }" v-el-height-adaptive-table="{ bottomOffset: 44 }"
> >
<el-table-column type="selection" width="55"></el-table-column> <el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="订单编号" width="110"> <el-table-column label="订单编号" width="110">
<template slot-scope="scope">{{ scope.row.number }}</template> <template slot-scope="scope">{{ scope.row.number }}</template>
</el-table-column> </el-table-column>
<el-table-column label="所需产品" show-overflow-tooltip width="150"> <el-table-column label="所需产品" show-overflow-tooltip width="150">
<template slot-scope="scope">{{ <template slot-scope="scope">{{scope.row.product_.name }}</template>
scope.row.product_.name
}}
</template>
</el-table-column> </el-table-column>
<el-table-column label="产品数量"> <el-table-column label="产品数量">
<template slot-scope="scope">{{ scope.row.count }}</template> <template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column> </el-table-column>
<el-table-column label="已派数量"> <el-table-column label="已派数量">
<template slot-scope="scope">{{ <template slot-scope="scope">{{scope.row.planed_count }}</template>
scope.row.planed_count
}}
</template>
</el-table-column> </el-table-column>
<el-table-column label="产品型号"> <el-table-column label="产品型号">
<template slot-scope="scope">{{ <template slot-scope="scope">{{scope.row.product_.specification }}</template>
scope.row.product_.specification
}}
</template>
</el-table-column> </el-table-column>
<el-table-column label="客户名称" show-overflow-tooltip width="150"> <el-table-column label="客户名称" show-overflow-tooltip width="150">
<template slot-scope="scope">{{ <template slot-scope="scope">{{scope.row.customer_.name}}</template>
scope.row.customer_.name
}}
</template>
</el-table-column> </el-table-column>
<el-table-column label="合同编号" show-overflow-tooltip width="150"> <el-table-column label="合同编号" show-overflow-tooltip width="150">
<template slot-scope="scope" v-if=" scope.row.contract_">{{ <template slot-scope="scope" v-if=" scope.row.contract_">{{scope.row.contract_.number }}</template>
scope.row.contract_.number
}}
</template>
</el-table-column> </el-table-column>
<el-table-column label="合同名称" show-overflow-tooltip width="150"> <el-table-column label="合同名称" show-overflow-tooltip width="150">
<template slot-scope="scope" v-if=" scope.row.contract_">{{ <template slot-scope="scope" v-if=" scope.row.contract_">{{scope.row.contract_.name }}</template>
scope.row.contract_.name
}}
</template>
</el-table-column> </el-table-column>
<el-table-column label="交货日期" width="110"> <el-table-column label="交货日期" width="110">
<template slot-scope="scope">{{ <template slot-scope="scope">{{scope.row.delivery_date }}</template>
scope.row.delivery_date
}}
</template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" width="110"> <el-table-column label="创建时间" width="110">
<template slot-scope="scope">{{ <template slot-scope="scope">{{scope.row.create_time }}</template>
scope.row.create_time
}}
</template>
</el-table-column> </el-table-column>
<el-table-column label="计划生产数" width="150px" fixed="right"> <el-table-column label="计划生产数" width="150px" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
@ -96,7 +68,6 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination <pagination
v-show="orderList.count > 0" v-show="orderList.count > 0"
:total="orderList.count" :total="orderList.count"
@ -127,7 +98,7 @@
fit fit
stripe stripe
style="width: 100%" style="width: 100%"
height="330" :height="domHeight"
ref="multipleTables" ref="multipleTables"
> >
<el-table-column type="selection" width="55"></el-table-column> <el-table-column type="selection" width="55"></el-table-column>
@ -194,10 +165,9 @@
fit fit
stripe stripe
style="width: 100%" style="width: 100%"
height="280" :height="domHeight"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="设备名称"> <el-table-column label="设备名称">
<template slot-scope="scope">{{ scope.row.name }}</template> <template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column> </el-table-column>
@ -268,6 +238,7 @@
components: {Pagination}, components: {Pagination},
data() { data() {
return { return {
domHeight:null,
orderplan: defaulteorderplan, orderplan: defaulteorderplan,
orderList: { orderList: {
count: 0, count: 0,
@ -397,5 +368,11 @@
}); });
}, },
}, },
mounted() {
let hei = document.getElementsByClassName('app-main')[0].clientHeight;//
let domHeight = this.domHeight = (hei - 116) / 2;
document.getElementById('orderList').style.height = domHeight + 'px';
document.getElementById('productionPlan').style.height = domHeight + 'px';
}
}; };
</script> </script>

View File

@ -3,9 +3,7 @@
<el-card class="box-card"> <el-card class="box-card">
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<span>生产任务列表</span> <span>生产任务列表</span>
</div> </div>
<el-table <el-table
:data="subproductionplanList.results" :data="subproductionplanList.results"
fit fit
@ -16,7 +14,6 @@
v-el-height-adaptive-table="{bottomOffset: 50}" v-el-height-adaptive-table="{bottomOffset: 50}"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="子计划编号" width="100px"> <el-table-column label="子计划编号" width="100px">
<template slot-scope="scope">{{scope.row.number}}</template> <template slot-scope="scope">{{scope.row.number}}</template>
</el-table-column> </el-table-column>
@ -29,8 +26,6 @@
<el-table-column label="名称" width="160px"> <el-table-column label="名称" width="160px">
<template slot-scope="scope" v-if="scope.row.subproduction_">{{ scope.row.subproduction_.name }}</template> <template slot-scope="scope" v-if="scope.row.subproduction_">{{ scope.row.subproduction_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="工序名"> <el-table-column label="工序名">
<template slot-scope="scope" v-if="scope.row.process_">{{ scope.row.process_.name }}</template> <template slot-scope="scope" v-if="scope.row.process_">{{ scope.row.process_.name }}</template>
</el-table-column> </el-table-column>
@ -42,9 +37,10 @@
<el-tag v-for="item in scope.row.steps" <el-tag v-for="item in scope.row.steps"
:key="item.number" :key="item.number"
:label="item.name" :label="item.name"
:value="item.number">{{item.name}}</el-tag> :value="item.number"
>
{{item.name}}
</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="生产车间" width="100px"> <el-table-column label="生产车间" width="100px">
@ -62,8 +58,6 @@
<el-table-column label="下达状态"> <el-table-column label="下达状态">
<template slot-scope="scope">{{ state_[scope.row.state] }}</template> <template slot-scope="scope">{{ state_[scope.row.state] }}</template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" width="160px"> <el-table-column label="创建时间" width="160px">
<template slot-scope="scope">{{ scope.row.create_time }}</template> <template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column> </el-table-column>
@ -74,23 +68,26 @@
fixed="right" fixed="right"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-link type="primary" <el-link
v-if="checkPermission(['warehouse_update'])" v-if="scope.row.state!==50&&checkPermission(['subplan_issue'])&&scope.row.production_plan_.state!==70&&scope.row.production_plan_.state!==80"
type="primary"
@click="handleclick(scope)" @click="handleclick(scope)"
>修改日期</el-link
> >
<el-link type="primary" 修改日期
v-if="scope.row.state==10" </el-link>
<el-link
v-if="scope.row.state===10&&checkPermission(['subplan_issue'])&&scope.row.production_plan_.state!==70&&scope.row.production_plan_.state!==80"
type="primary"
@click="handleissuedclick(scope)" @click="handleissuedclick(scope)"
>下达</el-link
> >
下达
<el-link type="primary" </el-link>
v-if="checkPermission(['warehouse_update'])" <el-link
type="primary"
@click="handleselectclick(scope)" @click="handleselectclick(scope)"
>查看详情</el-link
> >
查看详情
</el-link>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -133,8 +130,6 @@
> >
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div style="text-align: right"> <div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button> <el-button type="danger" @click="dialogVisible = false">取消</el-button>
@ -145,7 +140,6 @@
:visible.sync="dialogVisibles" :visible.sync="dialogVisibles"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
<el-table <el-table
:data="xhwl" :data="xhwl"
border border
@ -155,9 +149,6 @@
max-height="400" max-height="400"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="预计消耗"> <el-table-column label="预计消耗">
<template slot-scope="scope">{{ scope.row.count }}</template> <template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column> </el-table-column>
@ -179,7 +170,6 @@
<el-table-column label="物料单位"> <el-table-column label="物料单位">
<template slot-scope="scope">{{ scope.row.material_.unit }}</template> <template slot-scope="scope">{{ scope.row.material_.unit }}</template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<el-table <el-table
:data="ccwl" :data="ccwl"
@ -190,9 +180,6 @@
max-height="400" max-height="400"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="预计产出"> <el-table-column label="预计产出">
<template slot-scope="scope">{{ scope.row.count }}</template> <template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column> </el-table-column>
@ -214,11 +201,9 @@
<el-table-column label="物料单位"> <el-table-column label="物料单位">
<template slot-scope="scope">{{ scope.row.material_.unit }}</template> <template slot-scope="scope">{{ scope.row.material_.unit }}</template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div style="text-align: right"> <div style="text-align: right">
<el-button type="danger" @click="dialogVisibles = false">取消</el-button> <el-button type="danger" @click="dialogVisibles = false">取消</el-button>
</div> </div>
</el-dialog> </el-dialog>
</div> </div>
@ -229,8 +214,7 @@ import checkPermission from "@/utils/permission";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaultesubproductionplan = { const defaultesubproductionplan = {};
};
export default { export default {
components: {Pagination}, components: {Pagination},
data() { data() {
@ -260,7 +244,12 @@ export default {
20: '已下达', 20: '已下达',
30: '已接受', 30: '已接受',
40: '生产中', 40: '生产中',
50:'已完成'} 50: '已完成',
60: "军检完成",
70: "暂停",
80: "终止",
}
}; };
}, },
computed: {}, computed: {},
@ -283,8 +272,7 @@ export default {
this.listLoading = false; this.listLoading = false;
}); });
}, },
handleclick(scope) handleclick(scope) {
{
this.subproductionplan = Object.assign({}, scope.row); // copy obj this.subproductionplan = Object.assign({}, scope.row); // copy obj
this.dialogVisible = true; this.dialogVisible = true;
@ -294,8 +282,7 @@ export default {
}, },
handleselectclick(scope) handleselectclick(scope) {
{
this.dialogVisibles = true; this.dialogVisibles = true;
this.xhwl = []; this.xhwl = [];
@ -305,12 +292,9 @@ export default {
res.data.forEach((item) => { res.data.forEach((item) => {
if(item.type==1) if (item.type == 1) {
{
this.xhwl.push(item); this.xhwl.push(item);
} } else if (item.type == 2) {
else if(item.type==2)
{
this.ccwl.push(item); this.ccwl.push(item);
} }
@ -319,8 +303,7 @@ export default {
} }
}); });
}, },
confirm() confirm() {
{
updatesubproductionplan(this.subproductionplan.id, this.subproductionplan).then((res) => { updatesubproductionplan(this.subproductionplan.id, this.subproductionplan).then((res) => {
if (res.code >= 200) { if (res.code >= 200) {
this.getspList(); this.getspList();
@ -330,8 +313,7 @@ export default {
}); });
}, },
handleissuedclick(scope) handleissuedclick(scope) {
{
this.$confirm("确定下达子计划?", "提醒", { this.$confirm("确定下达子计划?", "提醒", {
confirmButtonText: "确认", confirmButtonText: "确认",
cancelButtonText: "取消", cancelButtonText: "取消",

View File

@ -43,7 +43,6 @@
fit fit
stripe stripe
highlight-current-row highlight-current-row
max-height="700"
height="100" height="100"
v-el-height-adaptive-table="{ bottomOffset: 43 }" v-el-height-adaptive-table="{ bottomOffset: 43 }"
> >
@ -73,7 +72,7 @@
订单项 订单项
</el-link> </el-link>
<el-link <el-link
v-if="checkPermission(['puorder_hear']) &&scope.row.is_audited == false" v-if="checkPermission(['puorder_audit']) &&scope.row.is_audited == false"
type="primary" type="primary"
@click="handleAudit(scope)" @click="handleAudit(scope)"
> >

View File

@ -2,9 +2,13 @@
<div class="app-container"> <div class="app-container">
<el-card> <el-card>
<div> <div>
<el-button type="primary" icon="el-icon-plus" @click="handleCreate" <el-button
>新增采购订单项</el-button type="primary"
icon="el-icon-plus"
@click="handleCreate"
> >
新增采购订单项
</el-button>
</div> </div>
</el-card> </el-card>
<el-card style="margin-top: 2px"> <el-card style="margin-top: 2px">
@ -26,7 +30,9 @@
<el-table-column label="物料型号"> <el-table-column label="物料型号">
<template slot-scope="scope">{{ scope.row.material_.specification }}</template> <template slot-scope="scope">{{ scope.row.material_.specification }}</template>
</el-table-column> </el-table-column>
<!--<el-table-column label="物料品牌">
<template slot-scope="scope">{{ scope.row.brand }}</template>
</el-table-column>-->
<el-table-column label="采购数量"> <el-table-column label="采购数量">
<template slot-scope="scope">{{ scope.row.count }}</template> <template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column> </el-table-column>
@ -36,15 +42,14 @@
<el-table-column label="截止到货时间"> <el-table-column label="截止到货时间">
<template slot-scope="scope">{{ scope.row.delivery_date }}</template> <template slot-scope="scope">{{ scope.row.delivery_date }}</template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="操作" width="220px"> <el-table-column align="center" label="操作" width="220px">
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
v-if="checkPermission(['vendor_delete'])"
type="danger" type="danger"
@click="handleDelete(scope)" @click="handleDelete(scope)"
>删除</el-link
> >
删除
</el-link>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -88,6 +93,9 @@
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!--<el-form-item label="物料品牌">
<el-input v-model="puorderTtem.brand" placeholder="规格型号"/>
</el-form-item>-->
</el-form> </el-form>
<div style="text-align: right"> <div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button> <el-button type="danger" @click="dialogVisible = false">取消</el-button>

View File

@ -43,9 +43,8 @@
fit fit
stripe stripe
highlight-current-row highlight-current-row
max-height="700"
height="100" height="100"
v-el-height-adaptive-table="{bottomOffset: 50}" v-el-height-adaptive-table="{bottomOffset: 42}"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="供应商名" prop="name"> <el-table-column label="供应商名" prop="name">
@ -56,8 +55,8 @@
</el-table-column> </el-table-column>
<el-table-column label="地址" prop="address" min-width="120" show-overflow-tooltip> <el-table-column label="地址" prop="address" min-width="120" show-overflow-tooltip>
</el-table-column> </el-table-column>
<el-table-column label="供应物料" prop="material"> <!-- <el-table-column label="供应物料" prop="material">
</el-table-column> </el-table-column>-->
<el-table-column label="备注" prop="description"> <el-table-column label="备注" prop="description">
</el-table-column> </el-table-column>
<el-table-column label="创建时间" prop="create_time" width="160"> <el-table-column label="创建时间" prop="create_time" width="160">

View File

@ -4,14 +4,13 @@
<el-tabs v-model="activeName" type="card" @tab-click="handleClick"> <el-tabs v-model="activeName" type="card" @tab-click="handleClick">
<el-tab-pane label="总览" name="1"> <el-tab-pane label="总览" name="1">
<el-table <el-table
v-loading="listLoading"
:data="fifodetailList1.results" :data="fifodetailList1.results"
border border
fit fit
stripe stripe
highlight-current-row highlight-current-row
height="620" height="100"
v-el-height-adaptive-table="{bottomOffset: 40}" v-el-height-adaptive-table="{bottomOffset: 42}"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="物料批次"> <el-table-column label="物料批次">
@ -57,7 +56,7 @@
<el-table-column label="创建时间"> <el-table-column label="创建时间">
<template slot-scope="scope">{{scope.row.create_time}}</template> <template slot-scope="scope">{{scope.row.create_time}}</template>
</el-table-column> </el-table-column>
<el-table-column <!-- <el-table-column
align="center" align="center"
label="操作" label="操作"
> >
@ -69,7 +68,7 @@
复验记录 复验记录
</el-link> </el-link>
</template> </template>
</el-table-column> </el-table-column>-->
</el-table> </el-table>
<pagination <pagination
v-show="fifodetailList1.count > 0" v-show="fifodetailList1.count > 0"
@ -87,8 +86,8 @@
fit fit
stripe stripe
highlight-current-row highlight-current-row
height="620" height="100"
v-el-height-adaptive-table="{bottomOffset: 40}" v-el-height-adaptive-table="{bottomOffset: 42}"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="物料批次"> <el-table-column label="物料批次">
@ -127,7 +126,7 @@
stripe stripe
highlight-current-row highlight-current-row
height="620" height="620"
v-el-height-adaptive-table="{bottomOffset: 40}" v-el-height-adaptive-table="{bottomOffset: 42}"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="物料批次"> <el-table-column label="物料批次">
@ -164,7 +163,7 @@
<el-table-column label="创建时间"> <el-table-column label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template> <template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column> </el-table-column>
<el-table-column <!--<el-table-column
align="center" align="center"
label="操作" label="操作"
> >
@ -185,7 +184,7 @@
复验记录 复验记录
</el-link> </el-link>
</template> </template>
</el-table-column> </el-table-column>-->
</el-table> </el-table>
<pagination <pagination
v-show="fifodetailList3.count > 0" v-show="fifodetailList3.count > 0"
@ -204,7 +203,7 @@
stripe stripe
highlight-current-row highlight-current-row
height="620" height="620"
v-el-height-adaptive-table="{bottomOffset: 40}" v-el-height-adaptive-table="{bottomOffset: 42}"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="物料批次"> <el-table-column label="物料批次">
@ -235,7 +234,7 @@
<el-table-column label="创建时间"> <el-table-column label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template> <template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column> </el-table-column>
<el-table-column <!--<el-table-column
align="center" align="center"
label="操作" label="操作"
> >
@ -256,7 +255,7 @@
复验记录 复验记录
</el-link> </el-link>
</template> </template>
</el-table-column> </el-table-column>-->
</el-table> </el-table>
<pagination <pagination
v-show="fifodetailList4.count > 0" v-show="fifodetailList4.count > 0"
@ -273,7 +272,7 @@
<script> <script>
import {getfifodetailList} from "@/api/inm"; import {getfifodetailList} from "@/api/inm";
import checkPermission from "@/utils/permission"; import checkPermission from "@/utils/permission";
import {createTestrecord} from "@/api/inm"; // import {createTestrecord} from "@/api/inm";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
export default { export default {

View File

@ -8,7 +8,6 @@
fit fit
stripe stripe
highlight-current-row highlight-current-row
max-height="700"
height="100" height="100"
v-el-height-adaptive-table="{bottomOffset: 42}" v-el-height-adaptive-table="{bottomOffset: 42}"
> >

View File

@ -7,7 +7,8 @@
fit fit
stripe stripe
highlight-current-row highlight-current-row
max-height="600" height="100"
v-el-height-adaptive-table="{bottomOffset: 42}"
> >
<el-table-column type="index" label="序号" width="50"/> <el-table-column type="index" label="序号" width="50"/>
<el-table-column label="产品编号"> <el-table-column label="产品编号">
@ -111,6 +112,10 @@
@click="handleRecordDetail(scope)" @click="handleRecordDetail(scope)"
>查看 >查看
</el-link> </el-link>
<el-link
@click="handleRecordExport(scope)"
>导出
</el-link>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -145,7 +150,7 @@
<el-col v-for="item in fieldList" :key="item.id" :span="24"> <el-col v-for="item in fieldList" :key="item.id" :span="24">
<div class="items" v-if="item.field_type==='draw'" style="height: 400px"> <div class="items" v-if="item.field_type==='draw'" style="height: 400px">
<span class="itemLabel">{{item.field_name}}</span> <span class="itemLabel">{{item.field_name}}</span>
<img style="width: 45%;vertical-align: text-top;" :src="'http://49.232.14.174:2222'+item.field_value"/> <img style="width: 45%;vertical-align: text-top;" :src="item.field_value"/>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
@ -154,11 +159,11 @@
</div> </div>
</template> </template>
<script> <script>
import {getfifodetailList} from "@/api/inm"; // import {getfifodetailList} from "@/api/inm";
import checkPermission from "@/utils/permission"; import checkPermission from "@/utils/permission";
import {mtest, getwproductList} from "@/api/wpm"; import {mtest, getwproductList} from "@/api/wpm";
import {getrecordformList, getrffieldList} from "@/api/mtm"; // import {getrecordformList, getrffieldList} from "@/api/mtm";
import {getTestRecord, getTestRecordItem} from "@/api/qm"; import {getTestRecord, getTestRecordItem,getTestRecordExport} from "@/api/qm";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
export default { export default {
@ -278,6 +283,18 @@
} }
}) })
}, },
handleRecordExport(scope){
let exportFormId = scope.row.id;
getTestRecordExport(exportFormId).then(res=>{
if(res.code===200){
let link = document.createElement('a');
link.href = res.data.path;
document.body.appendChild(link);
link.click();
}
})
},
}, },
}; };
</script> </script>

View File

@ -99,7 +99,6 @@
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
v-if="checkPermission(['material_delete'])"
type="primary" type="primary"
@click="handleoption(scope)" @click="handleoption(scope)"
>查看 >查看
@ -137,7 +136,6 @@
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
v-if="checkPermission(['material_delete'])"
type="primary" type="primary"
@click="handleprocess(scope)" @click="handleprocess(scope)"
>查看 >查看

View File

@ -48,6 +48,7 @@
<el-table-column align="center" label="操作"> <el-table-column align="center" label="操作">
<template slot-scope="scope"> <template slot-scope="scope">
<el-link @click="handleRecordDetail(scope)">查看</el-link> <el-link @click="handleRecordDetail(scope)">查看</el-link>
<el-link @click="handleRecordExport(scope)">导出</el-link>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -79,7 +80,7 @@
<el-col v-for="item in fieldList" :key="item.id" :span="24"> <el-col v-for="item in fieldList" :key="item.id" :span="24">
<div class="items" v-if="item.field_type==='draw'" style="height: 400px"> <div class="items" v-if="item.field_type==='draw'" style="height: 400px">
<span class="itemLabel">{{item.field_name}}</span> <span class="itemLabel">{{item.field_name}}</span>
<img style="width: 45%;vertical-align: text-top;" :src="'http://49.232.14.174:2222'+item.field_value"/> <img style="width: 45%;vertical-align: text-top;" :src="item.field_value"/>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
@ -90,8 +91,7 @@
<script> <script>
import checkPermission from "@/utils/permission"; import checkPermission from "@/utils/permission";
import {getProductionplan} from "@/api/pm"; import {getProductionplan} from "@/api/pm";
import {getTestRecord, getTestRecordItem} from "@/api/qm"; import {getTestRecord, getTestRecordItem,getTestRecordExport} from "@/api/qm";
export default { export default {
data() { data() {
return { return {
@ -175,6 +175,18 @@
} }
}) })
}, },
handleRecordExport(scope){
let exportFormId = scope.row.id;
// debugger;
getTestRecordExport(exportFormId).then(res=>{
if(res.code===200){
let link = document.createElement('a');
link.href = res.data.path;
document.body.appendChild(link);
link.click();
}
})
},
}, },
}; };
</script> </script>

View File

@ -4,12 +4,14 @@
<el-tabs v-model="activeName" type="card"> <el-tabs v-model="activeName" type="card">
<el-tab-pane label="成品不合格" name="1"> <el-tab-pane label="成品不合格" name="1">
<el-table <el-table
v-loading="listLoading"
:data="wproductList.results" :data="wproductList.results"
border border
fit fit
stripe stripe
highlight-current-row highlight-current-row
max-height="600" height="100"
v-el-height-adaptive-table="{bottomOffset: 42}"
> >
<el-table-column type="index" label="序号" width="50"/> <el-table-column type="index" label="序号" width="50"/>
<el-table-column label="产品编号"> <el-table-column label="产品编号">
@ -70,8 +72,8 @@
fit fit
stripe stripe
highlight-current-row highlight-current-row
height="620" height="100"
v-el-height-adaptive-table="{ bottomOffset: 40 }" v-el-height-adaptive-table="{bottomOffset: 42}"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="玻璃编号"> <el-table-column label="玻璃编号">
@ -129,14 +131,13 @@
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="入厂不合格" name="4"> <el-tab-pane label="入厂不合格" name="4">
<el-table <el-table
v-loading="listLoading"
:data="fifodetailList4.results" :data="fifodetailList4.results"
border border
fit fit
stripe stripe
highlight-current-row highlight-current-row
height="620" height="100"
v-el-height-adaptive-table="{bottomOffset: 40}" v-el-height-adaptive-table="{bottomOffset: 42}"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="物料批次"> <el-table-column label="物料批次">
@ -274,7 +275,7 @@
<el-col v-for="item in recordFieldList" :key="item.id" :span="24"> <el-col v-for="item in recordFieldList" :key="item.id" :span="24">
<div class="items" v-if="item.field_type==='draw'" style="height: 400px"> <div class="items" v-if="item.field_type==='draw'" style="height: 400px">
<span class="itemLabel">{{item.field_name}}</span> <span class="itemLabel">{{item.field_name}}</span>
<img style="width: 45%;vertical-align: text-top;" :src="'http://49.232.14.174:2222'+item.field_value"/> <img style="width: 45%;vertical-align: text-top;" :src="item.field_value"/>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
@ -390,7 +391,7 @@
//不合格玻璃审理单查看 //不合格玻璃审理单查看
handledetailbhg(scope) { handledetailbhg(scope) {
this.$router.push({name: "ticketDetail", params: {ticketId: scope.row.ticket}}) this.$router.push({name: "ticketDetail", params: {ticketId: scope.row.ticket,workflow:scope.row.workflow}})
}, },
//入场检验不合格 //入场检验不合格

View File

@ -1,12 +1,12 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-card style="margin-top: 2px"> <el-card style="margin-top: 2px">
<el-descriptions title="基本信息" :column="8" :size="size" border> <el-descriptions title="基本信息" :column="8" :size="size" border>
<el-descriptions-item label="合同名称"> {{contractdetail.name}}</el-descriptions-item> <el-descriptions-item label="合同名称"> {{contractdetail.name}}</el-descriptions-item>
<el-descriptions-item label="编号"> {{contractdetail.number}}</el-descriptions-item> <el-descriptions-item label="编号"> {{contractdetail.number}}</el-descriptions-item>
<el-descriptions-item label="金额"> {{contractdetail.amount}}</el-descriptions-item> <el-descriptions-item label="金额"> {{contractdetail.amount}}</el-descriptions-item>
<el-descriptions-item label="客户名称" v-if="contractdetail.customer"> {{contractdetail.customer_.name}} </el-descriptions-item> <el-descriptions-item label="客户名称" v-if="contractdetail.customer"> {{contractdetail.customer_.name}}
</el-descriptions-item>
</el-descriptions> </el-descriptions>
</el-card> </el-card>
<el-card class="box-card"> <el-card class="box-card">
@ -21,17 +21,14 @@
stripe stripe
highlight-current-row highlight-current-row
height="510px" height="510px"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="订单编号" width="160" show-overflow-tooltip> <el-table-column label="订单编号" width="160" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.number }}</template> <template slot-scope="scope">{{ scope.row.number }}</template>
</el-table-column> </el-table-column>
<el-table-column label="客户" width="200" show-overflow-tooltip> <el-table-column label="客户" width="200" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.customer_.name }}</template> <template slot-scope="scope">{{ scope.row.customer_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="产品名称" width="200" show-overflow-tooltip> <el-table-column label="产品名称" width="200" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.product_.name }}</template> <template slot-scope="scope">{{ scope.row.product_.name }}</template>
</el-table-column> </el-table-column>
@ -47,7 +44,6 @@
<el-table-column label="已交货数量"> <el-table-column label="已交货数量">
<template slot-scope="scope">{{ scope.row.delivered_count }}</template> <template slot-scope="scope">{{ scope.row.delivered_count }}</template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" width="160"> <el-table-column label="创建时间" width="160">
<template slot-scope="scope">{{ scope.row.create_time }}</template> <template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column> </el-table-column>
@ -57,16 +53,12 @@
width="220px" width="220px"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
v-if="checkPermission(['warehouse_delete'])"
type="primary" type="primary"
@click="handleDetail(scope)" @click="handleDetail(scope)"
>详情</el-link
> >
详情
</el-link>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -128,7 +128,7 @@
:rules="rule1" :rules="rule1"
> >
<el-form-item label="订单编号" prop="number"> <el-form-item label="订单编号" prop="number">
<el-input v-model="order.number" placeholder="订单编号自动生成" disabled="true"/> <el-input v-model="order.number" placeholder="订单编号"/>
</el-form-item> </el-form-item>
<el-form-item label="所需产品" prop="product"> <el-form-item label="所需产品" prop="product">
<el-select style="width: 100%" v-model="order.product" placeholder="请选择"> <el-select style="width: 100%" v-model="order.product" placeholder="请选择">
@ -224,8 +224,9 @@
dialogVisible: false, dialogVisible: false,
dialogType: "new", dialogType: "new",
rule1: { rule1: {
product: [{required: true, message: "请输入", trigger: "blur"}], number: [{required: true, message: "请输入订单编号", trigger: "blur"}],
delivery_date: [{required: true, message: "请输入", trigger: "blur"}], product: [{required: true, message: "请选择所需产品", trigger: "blur"}],
delivery_date: [{required: true, message: "请选择交货日期", trigger: "blur"}],
}, },
}; };
}, },

View File

@ -3,30 +3,30 @@
<el-card style="margin-top: 2px"> <el-card style="margin-top: 2px">
<el-descriptions title="基本信息" direction="vertical" :column="6" border> <el-descriptions title="基本信息" direction="vertical" :column="6" border>
<el-descriptions-item label="客户名称" v-if="salesdetail.customer"> <el-descriptions-item label="客户名称" v-if="salesdetail.customer">
{{ salesdetail.customer_.name }}</el-descriptions-item {{ salesdetail.customer_.name }}
> </el-descriptions-item>
<el-descriptions-item label="产品名称" v-if="salesdetail.product"> <el-descriptions-item label="产品名称" v-if="salesdetail.product">
{{ salesdetail.product_.name }}</el-descriptions-item {{ salesdetail.product_.name }}
> </el-descriptions-item>
<el-descriptions-item <el-descriptions-item
v-if="salesdetail.product"
label="产品型号" label="产品型号"
:span="2" :span="2"
v-if="salesdetail.product"
> >
{{ salesdetail.product_.specification }}</el-descriptions-item {{ salesdetail.product_.specification }}
> </el-descriptions-item>
<el-descriptions-item label="合同名称" v-if="salesdetail.order"> <el-descriptions-item label="合同名称" v-if="salesdetail.order">
{{ salesdetail.order_.contract_.name }}</el-descriptions-item {{ salesdetail.order_.contract_.name }}
> </el-descriptions-item>
<el-descriptions-item label="合同编号" v-if="salesdetail.order"> <el-descriptions-item label="合同编号" v-if="salesdetail.order">
{{ salesdetail.order_.contract_.number }}</el-descriptions-item {{ salesdetail.order_.contract_.number }}
> </el-descriptions-item>
<el-descriptions-item label="订单编号" v-if="salesdetail.order"> <el-descriptions-item label="订单编号" v-if="salesdetail.order">
{{ salesdetail.order_.number }} {{ salesdetail.order_.number }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="物流详情" v-if="ship_pic!=''"> <el-descriptions-item v-if="ship_pic!=''" label="物流详情">
<el-link type="primary" :href="salesdetail.ship_pic">物流单</el-link></el-descriptions-item> <el-link type="primary" :href="salesdetail.ship_pic">物流单</el-link>
</el-descriptions-item>
</el-descriptions> </el-descriptions>
<el-button type="primary" style="margin-top:10px" @click="upload">上传物流信息</el-button> <el-button type="primary" style="margin-top:10px" @click="upload">上传物流信息</el-button>
</el-card> </el-card>
@ -44,34 +44,32 @@
<el-table-column label="产品编号" show-overflow-tooltip> <el-table-column label="产品编号" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.number }}</template> <template slot-scope="scope">{{ scope.row.number }}</template>
</el-table-column> </el-table-column>
<el-table-column label="产品名称" show-overflow-tooltip> <el-table-column label="产品名称" show-overflow-tooltip>
<template slot-scope="scope">{{ <template slot-scope="scope">
scope.row.iproduct_.material_.name {{scope.row.iproduct_.material_.name }}
}}</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="批次"> <el-table-column label="批次">
<template slot-scope="scope">{{ <template slot-scope="scope">
scope.row.iproduct_.batch {{scope.row.iproduct_.batch }}
}}</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="仓库"> <el-table-column label="仓库">
<template slot-scope="scope">{{ <template slot-scope="scope">
scope.row.iproduct_.warehouse_.name {{scope.row.iproduct_.warehouse_.name }}
}}</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="是否已军检"> <el-table-column label="是否已军检">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.is_mtested == false">未军检</el-tag> <el-tag v-if="scope.row.is_mtested == false">未军检</el-tag>
<el-tag v-else>已军检</el-tag></template <el-tag v-else>已军检</el-tag>
> </template>
</el-table-column> </el-table-column>
<el-table-column label="军检"> <el-table-column label="军检">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.is_mtestok == false">不合格</el-tag> <el-tag v-if="scope.row.is_mtestok == false">不合格</el-tag>
<el-tag v-else>合格</el-tag></template <el-tag v-else>合格</el-tag>
> </template>
</el-table-column> </el-table-column>
<el-table-column label="装箱单号" show-overflow-tooltip> <el-table-column label="装箱单号" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.packnum }}</template> <template slot-scope="scope">{{ scope.row.packnum }}</template>
@ -82,24 +80,23 @@
<el-table-column align="center" label="操作" width="220px"> <el-table-column align="center" label="操作" width="220px">
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
v-if="checkPermission(['warehouse_delete'])"
type="primary" type="primary"
@click="handlePack(scope)" @click="handlePack(scope)"
>装箱</el-link
> >
装箱
</el-link>
<el-link <el-link
v-if="checkPermission(['warehouse_delete'])"
type="primary" type="primary"
@click="handleNotPack(scope)" @click="handleNotPack(scope)"
>备注</el-link
> >
备注
</el-link>
<el-link <el-link
v-if="checkPermission(['warehouse_delete'])"
type="danger" type="danger"
@click="handleDelete(scope)" @click="handleDelete(scope)"
>删除</el-link
> >
删除
</el-link>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -151,7 +148,6 @@
<el-form-item label="装箱单号" prop="packnum"> <el-form-item label="装箱单号" prop="packnum">
<el-input v-model="packData.packnum" placeholder="装箱单号"/> <el-input v-model="packData.packnum" placeholder="装箱单号"/>
</el-form-item> </el-form-item>
<el-form-item label="装箱文件确认" prop="iproducts"> <el-form-item label="装箱文件确认" prop="iproducts">
<el-table <el-table
:data="packlist" :data="packlist"
@ -183,22 +179,22 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="库存数量"> <el-table-column label="库存数量">
<template slot-scope="scope" v-if="scope.row.material_">{{ <template slot-scope="scope" v-if="scope.row.material_">
scope.row.material_.count {{scope.row.material_.count}}
}}</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="安全库存数量"> <el-table-column label="安全库存数量">
<template slot-scope="scope" v-if="scope.row.material_">{{ <template slot-scope="scope" v-if="scope.row.material_">
scope.row.material_.count_safe {{scope.row.material_.count_safe}}
}}</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div style="text-align: right"> <div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false" <el-button type="danger" @click="dialogVisible = false">
>取消</el-button 取消
> </el-button>
<el-button type="primary" @click="submitPack">确认</el-button> <el-button type="primary" @click="submitPack">确认</el-button>
</div> </div>
</el-dialog> </el-dialog>
@ -219,9 +215,9 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<div style="text-align: right"> <div style="text-align: right">
<el-button type="danger" @click="dialogVisibles = false" <el-button type="danger" @click="dialogVisibles = false">
>取消</el-button 取消
> </el-button>
<el-button type="primary" @click="submitnotPack">确认</el-button> <el-button type="primary" @click="submitnotPack">确认</el-button>
</div> </div>
</el-dialog> </el-dialog>
@ -307,8 +303,7 @@ export default {
}, },
uploadship() uploadship() {
{
console.log(this.ship); console.log(this.ship);
ship(this.id, this.ship).then((res) => { ship(this.id, this.ship).then((res) => {
if (res.code >= 200) { if (res.code >= 200) {

View File

@ -39,20 +39,17 @@
width="220px" width="220px"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
v-if="checkPermission(['customfield_update'])"
@click="handleEdit(scope)" @click="handleEdit(scope)"
>编辑
</el-link
> >
编辑
</el-link>
<el-link <el-link
v-if="checkPermission(['customfield_delete'])"
type="danger" type="danger"
@click="handleDeleteCustomfield(scope)" @click="handleDeleteCustomfield(scope)"
>删除
</el-link
> >
删除
</el-link>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -119,7 +119,7 @@
</el-col> </el-col>
</el-row> </el-row>
<div style="width: 90%;margin: auto;"> <div style="width: 90%;margin: auto;">
<svg height=1000 id="mySvg" style="width:100%!important;"> <svg height=1500 id="mySvg" style="width:100%!important;">
</svg> </svg>
</div> </div>
</div> </div>
@ -356,7 +356,7 @@
var g = new dagreD3.graphlib.Graph().setGraph({ var g = new dagreD3.graphlib.Graph().setGraph({
rankdir: 'DL', rankdir: 'DL',
nodesep: 100, nodesep: 100,
edgesep: 10,//两条线之间的距离 edgesep: 50,//两条线之间的距离
ranksep: 50,//节点之间的距离 ranksep: 50,//节点之间的距离
marginx: 160, marginx: 160,
marginy: 20, marginy: 20,

View File

@ -1,11 +1,14 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-card> <el-card>
<div style="margin-top: 2px"> <div style="margin-top: 2px">
<el-button type="primary" icon="el-icon-plus" @click="handleCreate" <el-button
>新增</el-button type="primary"
icon="el-icon-plus"
@click="handleCreate"
> >
新增
</el-button>
</div> </div>
</el-card> </el-card>
<el-card style="margin-top: 2px"> <el-card style="margin-top: 2px">
@ -34,29 +37,24 @@
<el-table-column width="180" label="创建时间"> <el-table-column width="180" label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template> <template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
align="center" align="center"
label="操作" label="操作"
width="220px" width="220px"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-link @click="handleEdit(scope)">
编辑
</el-link>
<el-link <el-link
v-if="checkPermission(['wftransition_update'])"
@click="handleEdit(scope)"
>编辑</el-link
>
<el-link
v-if="checkPermission(['wftransition_delete'])"
type="danger" type="danger"
@click="handleDelete(scope)" @click="handleDelete(scope)"
>删除</el-link
> >
删除
</el-link>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-card> </el-card>
<el-dialog <el-dialog
:visible.sync="dialogVisible" :visible.sync="dialogVisible"
@ -76,7 +74,6 @@
<el-input v-model="wftransition.timer" type="number" placeholder="0"/> <el-input v-model="wftransition.timer" type="number" placeholder="0"/>
</el-form-item> </el-form-item>
<el-form-item label="源状态" prop="source_state"> <el-form-item label="源状态" prop="source_state">
<el-select v-model="wftransition.source_state" placeholder="请选择" style="width:100%"> <el-select v-model="wftransition.source_state" placeholder="请选择" style="width:100%">
<el-option <el-option
v-for="item in stateoptions" v-for="item in stateoptions"
@ -116,9 +113,7 @@
</el-form-item> </el-form-item>
<el-form-item label="是否校验必填" prop="field_require_check"> <el-form-item label="是否校验必填" prop="field_require_check">
<el-switch v-model="wftransition.field_require_check"></el-switch> <el-switch v-model="wftransition.field_require_check"></el-switch>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div style="text-align: right"> <div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button> <el-button type="danger" @click="dialogVisible = false">取消</el-button>
@ -128,10 +123,17 @@
</div> </div>
</template> </template>
<script> <script>
import {getWfStateList, getWfTransitionList, createWfTransition,updateWfTransition,deleteWfTransition } from "@/api/workflow"; import {
getWfStateList,
getWfTransitionList,
createWfTransition,
updateWfTransition,
deleteWfTransition
} from "@/api/workflow";
import checkPermission from "@/utils/permission"; import checkPermission from "@/utils/permission";
import vueJsonEditor from 'vue-json-editor' import vueJsonEditor from 'vue-json-editor'
import {genTree} from "@/utils" import {genTree} from "@/utils"
const defaultwftransition = { const defaultwftransition = {
name: "", name: "",
}; };

View File

@ -16,9 +16,10 @@
:data="subPlanList" :data="subPlanList"
fit fit
style="width: 100%" style="width: 100%"
height="100"
stripe stripe
border border
height="100"
highlight-current-row
v-el-height-adaptive-table="{bottomOffset: 50}" v-el-height-adaptive-table="{bottomOffset: 50}"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
@ -70,7 +71,7 @@
首件检验 首件检验
</el-link> </el-link>
<el-link <el-link
v-else-if="checkPermission(['first_test'])&&scope.row.first_test!==null&&!scope.row.first_test_.is_submited" v-else-if="checkPermission(['first_test'])&&scope.row.first_test!==null&&scope.row.first_test_.is_submited!==true"
type="primary" type="primary"
@click="handleTestContinue(scope)" @click="handleTestContinue(scope)"
> >
@ -90,6 +91,13 @@
> >
查看 查看
</el-link> </el-link>
<el-link
v-if="scope.row.leader_1!==null&&scope.row.leader_2!==null&&scope.row.leader_3!==null"
type="primary"
@click="handleExportClick(scope)"
>
导出
</el-link>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -215,12 +223,19 @@
</div> </div>
</el-row> </el-row>
</el-dialog> </el-dialog>
<el-dialog :visible.sync="limitedPhoto" @close="closeCamera" id="loginFaceWrap"> <el-dialog :visible.sync="limitedPhoto" @close="closeCamera" id="loginFaceWrap">
<div style="font-size: 28px;color: #333333;text-align: center;font-weight: bold;">审核人员确认</div> <div style="font-size: 28px;color: #333333;text-align: center;font-weight: bold;">审核人员确认</div>
<div class="testTracking"> <div class="testTracking">
<faceLogin v-if="limitedPhoto" ref="faceTracking" name="faceLogin" @func="getMsgFormSon"></faceLogin> <faceLogin v-if="limitedPhoto" ref="faceTracking" name="faceLogin" @func="getMsgFormSon"></faceLogin>
</div> </div>
</el-dialog> </el-dialog>
<el-dialog :visible.sync="limitedUserCheck" @close="closeCamera" id="userCheckWrap">
<div style="font-size: 28px;color: #333333;text-align: center;font-weight: bold;">审核人员确认</div>
<div class="testTracking">
<faceLogin v-if="limitedUserCheck" ref="faceTracking" name="userCheck" @func="checkSubmit"></faceLogin>
</div>
</el-dialog>
</div> </div>
</template> </template>
@ -231,6 +246,7 @@
import faceLogin from '@/components/faceLogin/review.vue'; import faceLogin from '@/components/faceLogin/review.vue';
import {getProcessList,getrecordformList} from "@/api/mtm"; import {getProcessList,getrecordformList} from "@/api/mtm";
import {getsubplanList} from "@/api/wpm"; import {getsubplanList} from "@/api/wpm";
import {getTestRecordExport} from "@/api/qm";
import {firstTestInit,firstAudit} from "@/api/pm"; import {firstTestInit,firstAudit} from "@/api/pm";
import {getTestRecordItem,putTestRecordItem,subTestRecordItem} from "@/api/qm"; import {getTestRecordItem,putTestRecordItem,subTestRecordItem} from "@/api/qm";
@ -256,6 +272,11 @@
enabled:true, enabled:true,
material:null material:null
}, },
checkParams:{
id:null,
is_testok:true,
record_data:null,
},
planId:null, planId:null,
leader:null, leader:null,
recordId: null, recordId: null,
@ -272,6 +293,7 @@
reviewVisible:false, reviewVisible:false,
recordVisible:false, recordVisible:false,
is_midtesting:false, is_midtesting:false,
limitedUserCheck:false,
is_testok:false, is_testok:false,
formName:'首件确认检查表', formName:'首件确认检查表',
update_time:'', update_time:'',
@ -296,6 +318,8 @@
changeIndex(item,index) { changeIndex(item,index) {
this.activeIndex = index; this.activeIndex = index;
this.listQuery.process = item.id; this.listQuery.process = item.id;
this.subPlanList = [];
this.count = 0;
this.getTableData(); this.getTableData();
}, },
@ -341,6 +365,7 @@
//首件审批 //首件审批
handleSelectclick(scope,index){ handleSelectclick(scope,index){
let that = this; let that = this;
debugger;
this.reviewVisible = true; this.reviewVisible = true;
that.planId = scope.row.id; that.planId = scope.row.id;
that.leader_1 = scope.row.leader_1_?scope.row.leader_1_.name:null; that.leader_1 = scope.row.leader_1_?scope.row.leader_1_.name:null;
@ -445,20 +470,45 @@
}); });
}, },
//提交首件检查 //提交首件检查:需要人脸识别进行身份验证
recordSubmit(value) { recordSubmit(value) {
let that = this; let that = this;
let id = value.id;
let params = {}; let params = {};
params.record_data = value.record_data; params.id = value.id;
params.is_testok = value.is_testok; params.is_testok = value.is_testok;
params.record_data = value.record_data;
that.checkParams = params;
that.limitedUserCheck = true;
},
//人脸识别获取人员信息后
checkSubmit(data){
let that =this;
let id = that.checkParams.id;
let params = new Object();
params.is_testok = that.checkParams.is_testok;
params.record_data = that.checkParams.record_data;
params.token = data.token;
let text = '确定以操作员'+data.name+'身份提交?';
if(data.token!==''&&data.token!==null&&data.token!==undefined) {
this.$confirm(text, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
putTestRecordItem(id, params).then((res) => { putTestRecordItem(id, params).then((res) => {
if (res.code >= 200) { if (res.code >= 200) {
subTestRecordItem(id, params).then((res) => { subTestRecordItem(id, params).then((res) => {
debugger;
that.limitedUserCheck = false;
if (res.code >= 200) { if (res.code >= 200) {
that.recordVisible = false; that.recordVisible = false;
that.getTableData(); that.getTableData();
}else{
that.$message.error(res.msg)
} }
}).catch(()=>{
that.limitedUserCheck = false;
}); });
} else { } else {
that.$message.error(res.msg) that.$message.error(res.msg)
@ -466,6 +516,10 @@
}).catch((err) => { }).catch((err) => {
that.$message.error(err); that.$message.error(err);
}); });
}).catch(() => {
that.limitedUserCheck = false;
});
}
}, },
//再次点击首件检验 //再次点击首件检验
@ -550,6 +604,17 @@
}) })
} }
}, },
handleExportClick(scope){
let exportFormId = scope.row.id;
getTestRecordExport(exportFormId).then(res=>{
if(res.code===200){
let link = document.createElement('a');
link.href = res.data.path;
document.body.appendChild(link);
link.click();
}
})
},
}, },
mounted() { mounted() {
this.getProcessList(); this.getProcessList();

View File

@ -61,6 +61,8 @@
> >
<template slot-scope="scope">{{ scope.row.step_.name }}</template> <template slot-scope="scope">{{ scope.row.step_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" prop="create_time">
</el-table-column>
<el-table-column align="center" label="操作" width="220px"> <el-table-column align="center" label="操作" width="220px">
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
@ -76,7 +78,6 @@
检验记录 检验记录
</el-link> </el-link>
<el-link <el-link
v-if="checkPermission(['wp_scrap'])"
type="danger" type="danger"
@click="handleScrapbcp(scope)" @click="handleScrapbcp(scope)"
> >
@ -176,6 +177,8 @@
> >
<template slot-scope="scope">{{ scope.row.step_.name }}</template> <template slot-scope="scope">{{ scope.row.step_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" prop="create_time">
</el-table-column>
<el-table-column align="center" label="操作" width="220px"> <el-table-column align="center" label="操作" width="220px">
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
@ -267,7 +270,12 @@
<template slot-scope="scope">{{ scope.row.step_.name }}</template> <template slot-scope="scope">{{ scope.row.step_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="检验员"> <el-table-column label="检验员">
<!--<template slot-scope="scope">{{}}</template>--> <template slot-scope="scope">
<span v-if="scope.row.update_by_!==null">{{scope.row.update_by_.username}}</span>
<span v-else>{{scope.row.create_by_.username}}</span>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="create_time">
</el-table-column> </el-table-column>
<el-table-column align="center" label="操作" width="220px"> <el-table-column align="center" label="操作" width="220px">
<template slot-scope="scope"> <template slot-scope="scope">
@ -360,19 +368,24 @@
<template slot-scope="scope">{{ scope.row.subproduction_plan_.number }}</template> <template slot-scope="scope">{{ scope.row.subproduction_plan_.number }}</template>
</el-table-column> </el-table-column>
<el-table-column label="检验员"> <el-table-column label="检验员">
<!--<template slot-scope="scope">{{}}</template>--> <template slot-scope="scope">
<span v-if="scope.row.update_by_!==null">{{scope.row.update_by_.username}}</span>
<span v-else>{{scope.row.create_by_.username}}</span>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="create_time">
</el-table-column> </el-table-column>
<el-table-column align="center" label="操作" width="220px"> <el-table-column align="center" label="操作" width="220px">
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
v-if="checkPermission(['wmaterial_scrap'])" v-if="checkPermission(['wp_scrap'])"
type="danger" type="danger"
@click="handleScrap(scope)" @click="handleScrap(scope)"
> >
报废 报废
</el-link> </el-link>
<el-link <el-link
v-if="checkPermission(['operation_hear'])&&!scope.row.ticket" v-if="checkPermission(['operation_hear'])&&scope.row.ticket==null"
type="primary" type="primary"
@click="handleRetrial(scope)" @click="handleRetrial(scope)"
> >
@ -426,6 +439,8 @@
> >
<template slot-scope="scope">{{ scope.row.step_.name }}</template> <template slot-scope="scope">{{ scope.row.step_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" prop="create_time">
</el-table-column>
<el-table-column align="center" label="操作" width="220px"> <el-table-column align="center" label="操作" width="220px">
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
@ -471,7 +486,7 @@
</el-dialog> </el-dialog>
<!--复检检验表单--> <!--复检检验表单-->
<el-dialog <el-dialog
width="60%" width="75%"
:title="formName" :title="formName"
@close="recordCancel" @close="recordCancel"
:visible.sync="limitedReview" :visible.sync="limitedReview"
@ -491,7 +506,7 @@
@recordCancel="recordCancel" @recordCancel="recordCancel"
/> />
</el-dialog> </el-dialog>
<!--检查表显示--> <!--复检检验表单-->
<el-dialog <el-dialog
width="60%" width="60%"
:title="formName" :title="formName"
@ -505,6 +520,8 @@
:hasPicture="hasPicture" :hasPicture="hasPicture"
:formID="recordform" :formID="recordform"
:wproduct="wproduct" :wproduct="wproduct"
:remark="remark"
:numbers="numbers"
:recordId="recordId" :recordId="recordId"
:isDisabled="isDisabled" :isDisabled="isDisabled"
:isMidTesting="is_midtesting" :isMidTesting="is_midtesting"
@ -584,7 +601,7 @@
查看 查看
</el-link> </el-link>
<el-link <el-link
v-if="checkPermission(['wp_test_init'])" v-if="checkPermission(['testrecord_delete'])"
@click="delTestRecord(scope)" @click="delTestRecord(scope)"
> >
删除 删除
@ -732,13 +749,21 @@
</div> </div>
</el-col> </el-col>
<el-col v-for="item in fieldList" :key="item.id" :span="24"> <el-col v-for="item in fieldList" :key="item.id" :span="24">
<div class="items" v-if="item.field_type==='draw'" style="height: 400px"> <div class="items" v-if="item.field_type==='draw'" style="height: fit-content">
<span class="itemLabel">{{item.field_name}}</span> <span class="itemLabel">{{item.field_name}}</span>
<img style="width: 45%;vertical-align: text-top;" :src="'http://49.232.14.174:2222'+item.field_value"/> <img style="width: 45%;vertical-align: text-top;" :src="item.field_value"/>
</div> </div>
</el-col> </el-col>
<el-button @click="exportDom">导出</el-button>
</el-row> </el-row>
</el-dialog> </el-dialog>
<!--刷脸验证-->
<el-dialog :visible.sync="limitedPhoto" @close="closeCamera" id="loginFaceWrap">
<div style="font-size: 28px;color: #333333;text-align: center;font-weight: bold;">审核人员确认</div>
<div class="testTracking">
<faceLogin v-if="limitedPhoto" ref="faceTracking" name="faceLogin" @func="checkSubmit"></faceLogin>
</div>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
@ -748,18 +773,23 @@
import checkPermission from "@/utils/permission"; import checkPermission from "@/utils/permission";
import customForm from '@/components/customForm/index'; import customForm from '@/components/customForm/index';
import reviewForm from '@/components/customForm/review'; import reviewForm from '@/components/customForm/review';
import faceLogin from '@/components/faceLogin/review.vue';
import {createTicket, getWorkflowInit} from "@/api/workflow"; import {createTicket, getWorkflowInit} from "@/api/workflow";
import {getrecordformList, getrffieldList} from "@/api/mtm"; import {getrecordformList, getrffieldList} from "@/api/mtm";
import {getwproductList, wproductPutin, createputins, testInit, scrap, getRetrial} from "@/api/wpm"; import {getwproductList, wproductPutin, createputins, testInit, scrap, getRetrial} from "@/api/wpm";
import {getTestRecord, getTestRecordItem, putTestRecordItem, delTestRecordItem, subTestRecordItem} from "@/api/qm"; import {getTestRecord, getTestRecordItem, putTestRecordItem, delTestRecordItem, subTestRecordItem,getTestRecordExport} from "@/api/qm";
// import {genTree} from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
// import {saveAs} from "file-saver";
// import htmlDocx from "html-docx-js/dist/html-docx";
//import htmlToPdf from './../../utils/htmlToPdf';
const defaultetestitem = {}; const defaultetestitem = {};
export default { export default {
inject: ['reload'], inject: ['reload'],
components: {Pagination, customForm, reviewForm}, components: {Pagination, customForm, reviewForm, faceLogin},
data() { data() {
return { return {
exportFormId:null,
testitem: defaultetestitem, testitem: defaultetestitem,
formbcp: {}, formbcp: {},
form: {remark: "", warehouse: ""}, form: {remark: "", warehouse: ""},
@ -798,6 +828,11 @@
page: 1, page: 1,
page_size: 20, page_size: 20,
}, },
params: {
id: null,
is_testok: true,
record_data: null
},
activeName: "1", activeName: "1",
create_by_: '', create_by_: '',
update_time: '', update_time: '',
@ -874,6 +909,7 @@
mutipID: [], mutipID: [],
wproduct: null, wproduct: null,
isPost: false, isPost: false,
limitedPhoto: false,
is_midtesting: false, is_midtesting: false,
isDisabled: false, isDisabled: false,
origin_test: null, origin_test: null,
@ -901,7 +937,9 @@
filtersList: [{text: '切割', value: '切割'}, {text: '磨边', value: '磨边'}, filtersList: [{text: '切割', value: '切割'}, {text: '磨边', value: '磨边'},
{text: '清洗', value: '清洗'}, {text: '热弯成型', value: '热弯成型'}, {text: '化学钢化', value: '化学钢化'}, {text: '清洗', value: '清洗'}, {text: '热弯成型', value: '热弯成型'}, {text: '化学钢化', value: '化学钢化'},
{text: '镀膜', value: '镀膜'}, {text: '断膜', value: '断膜'}, {text: '汇流条制备', value: '汇流条制备'}, {text: '镀膜', value: '镀膜'}, {text: '断膜', value: '断膜'}, {text: '汇流条制备', value: '汇流条制备'},
{text: '夹层', value: '夹层'}, {text: '包边', value: '包边'}] {text: '夹层', value: '夹层'}, {text: '包边', value: '包边'}],
remark:'',
numbers:null,
}; };
}, },
computed: {}, computed: {},
@ -915,6 +953,20 @@
// this.getLists(); // this.getLists();
}, },
methods: { methods: {
exportDom() {
// htmlToPdf.downloadPDF(document.getElementById('pdfDom'), this.formName);
getTestRecordExport(this.exportFormId).then(res=>{
if(res.code===200){
debugger;
console.log(res.data.path)
let link = document.createElement('a');
link.href = res.data.path;
document.body.appendChild(link);
link.click();
}
})
},
checkPermission, checkPermission,
handleClick(tab) { handleClick(tab) {
this.listLoading = true; this.listLoading = true;
@ -931,6 +983,7 @@
this.getList3(); this.getList3();
} }
}, },
//待检半成品列表 //待检半成品列表
getList() { getList() {
this.listLoading = true; this.listLoading = true;
@ -1178,6 +1231,8 @@
that.innerIndex = index; that.innerIndex = index;
// this.outerVisible = true; // this.outerVisible = true;
that.wproduct = scope.row.id;//半成品ID that.wproduct = scope.row.id;//半成品ID
this.numbers = null;
this.remark = '';
that.listQueryrecordform.material = scope.row.material; that.listQueryrecordform.material = scope.row.material;
if (index === '3') { if (index === '3') {
that.listQueryrecordform.type = 40; that.listQueryrecordform.type = 40;
@ -1227,11 +1282,14 @@
//点击记录里的检验 //点击记录里的检验
handleInspectionRecord(scope) { handleInspectionRecord(scope) {
debugger;
let that = this; let that = this;
that.fieldList = []; that.fieldList = [];
that.recordVisible = false; that.recordVisible = false;
that.recordId = scope.row.id; that.recordId = scope.row.id;
that.recordform = scope.row.form; that.recordform = scope.row.form;
that.numbers = scope.row.number?scope.row.number:null;
that.remark = scope.row.remark?scope.row.remark:'';
that.formName = scope.row.form_.name; that.formName = scope.row.form_.name;
if (that.innerIndex !== '2') {//非复检 if (that.innerIndex !== '2') {//非复检
getrffieldList({form: this.recordform, enabled: true, page: 1, page_size: 100}).then((response) => { getrffieldList({form: this.recordform, enabled: true, page: 1, page_size: 100}).then((response) => {
@ -1309,11 +1367,14 @@
that.fieldList = []; that.fieldList = [];
that.create_by_ = scope.row.create_by_.name; that.create_by_ = scope.row.create_by_.name;
that.update_time = scope.row.update_time; that.update_time = scope.row.update_time;
that.exportFormId = scope.row.id;
getTestRecordItem(scope.row.id).then((res) => { getTestRecordItem(scope.row.id).then((res) => {
if (res.code >= 200) { if (res.code >= 200) {
that.recordFinishedVisible = true; that.recordFinishedVisible = true;
that.formName = res.data.form_.name; that.formName = res.data.form_.name;
that.fieldList = res.data.record_data; that.fieldList = res.data.record_data;
that.numbers = res.data.number?res.data.number:'';
that.remark = res.data.remark?res.data.remark:'';
} }
}) })
}, },
@ -1449,6 +1510,12 @@
let params = {}; let params = {};
params.record_data = value.record_data; params.record_data = value.record_data;
params.is_testok = value.is_testok; params.is_testok = value.is_testok;
if(value.number){
params.number = value.number;
}
if(value.remark){
params.remark = value.remark;
}
putTestRecordItem(id, params).then((res) => { putTestRecordItem(id, params).then((res) => {
if (res.code >= 200) { if (res.code >= 200) {
that.recordVisible = false; that.recordVisible = false;
@ -1466,13 +1533,45 @@
}); });
}, },
//记录提交检查项目 //记录提交检查项目出现人脸验证弹窗
recordSubmit(value) { recordSubmit(value) {
let that = this; let that = this;
let id = value.id;
let params = {}; let params = {};
params.record_data = value.record_data; params.id = value.id;
params.is_testok = value.is_testok; params.is_testok = value.is_testok;
params.record_data = value.record_data;
debugger;
if(value.number){
params.number = value.number;
}
if(value.remark){
params.remark = value.remark;
}
that.params = params;
that.limitedPhoto = true;
},
checkSubmit(data) {
debugger;
let that = this;
let id = that.params.id;
let params = new Object();
params.is_testok = that.params.is_testok;
params.record_data = that.params.record_data;
if(this.params.number){
params.number = this.params.number;
}
if(this.params.remark){
params.remark = this.params.remark;
}
params.token = data.token;
let text = '确定以操作员'+data.name+'身份提交?';
if (data.token !== '' && data.token !== null && data.token !== undefined) {
this.$confirm(text, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
that.limitedPhoto = false;
putTestRecordItem(id, params).then((res) => { putTestRecordItem(id, params).then((res) => {
if (res.code >= 200) { if (res.code >= 200) {
subTestRecordItem(id, params).then((res) => { subTestRecordItem(id, params).then((res) => {
@ -1485,14 +1584,21 @@
that.getList1(); that.getList1();
that.getList3(); that.getList3();
that.refreshRecord(); that.refreshRecord();
}
});
} else { } else {
this.$message.error(res.msg) that.$message.error(res.msg)
}
}).catch(() => {});
} else {
that.$message.error(res.msg)
} }
}).catch((err) => { }).catch((err) => {
this.$message.error(err); that.$message.error(err);
}); });
}).catch(() => {
that.limitedPhoto = false;
});
}
}, },
//第一次保存提交检查项目 //第一次保存提交检查项目
@ -1504,6 +1610,19 @@
this.getList1(); this.getList1();
this.getList3(); this.getList3();
}, },
/*关闭相机*/
closeCamera() {
this.$refs.faceTracking.closeCamera();
let video = document.getElementById('video');
let stream = video.srcObject;
// console.log(stream);
let tracks = stream.getTracks();
tracks.forEach(track => {
track.stop()
});
video.srcObject = null;
},
}, },
mounted() { mounted() {
getUserList({page: 0}).then(response => { getUserList({page: 0}).then(response => {

View File

@ -3,6 +3,7 @@
<el-card class="box-card"> <el-card class="box-card">
<el-tabs <el-tabs
type="border-card" type="border-card"
v-model="activeName"
@tab-click="handleClick" @tab-click="handleClick"
> >
<el-tab-pane <el-tab-pane
@ -23,44 +24,47 @@
v-el-height-adaptive-table="{bottomOffset: 50}" v-el-height-adaptive-table="{bottomOffset: 50}"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="任务编号">
<template slot-scope="scope">
<div v-for="(item,index) in scope.row.out_detail" :key="index">
{{item.plan.number}}
</div>
</template>
</el-table-column>
<el-table-column label="子工序工序"> <el-table-column label="子工序工序">
<template slot-scope="scope">{{scope.row.step_.name }}</template> <template slot-scope="scope">{{scope.row.step_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="是否提交"> <el-table-column label="是否提交">
<template slot-scope="scope"> <template slot-scope="scope">
<el-span v-if="scope.row.is_submited"></el-span> <span v-if="scope.row.is_submited"></span>
<el-span v-else></el-span> <span v-else></span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作人"> <el-table-column label="操作人">
<template slot-scope="scope"> <template slot-scope="scope">
{{scope.row.create_by_.username}} <span v-if="scope.row.update_by_!==null">{{scope.row.update_by_.username}}</span>
<span v-else>{{scope.row.create_by_.username}}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="过程记录表"> <el-table-column label="产品名称">
<template v-if="scope.row.record_" slot-scope="scope"> <template slot-scope="scope">
<el-tag <div v-for="(item,index) in scope.row.out_detail" :key="index">
v-for="item in scope.row.record_" {{item.product.name}}
:key="item.id" </div>
:label="item.name" </template>
:value="item.id" </el-table-column>
> <el-table-column label="规格型号">
{{item.name}} <template slot-scope="scope">
</el-tag> <div v-for="(item,index) in scope.row.out_detail" :key="index">
{{item.product.specification}}
</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="产品数量"> <el-table-column label="产品数量">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.count_work }} <div v-for="(item,index) in scope.row.out_detail" :key="index">
</template> {{item.count}}
</el-table-column> </div>
<el-table-column label="生产设备">
<template slot-scope="scope" v-if="scope.row.equip_">
<el-tag v-for="item in scope.row.equip_"
:key="item.id"
:label="item.number"
:value="item.id">{{item.number}}
</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间"> <el-table-column label="创建时间">
@ -122,6 +126,7 @@
page: 1, page: 1,
page_size: 20, page_size: 20,
}, },
activeName: "",
processOption: "", processOption: "",
}; };
}, },
@ -143,6 +148,10 @@
getProcessList({page: 0}).then((response) => { getProcessList({page: 0}).then((response) => {
if (response.data) { if (response.data) {
this.processOption = response.data; this.processOption = response.data;
this.activeName = response.data[0].id;
this.process = response.data[0].id;
this.listQuery.step__process = response.data[0].id;
this.getList();
} }
}); });
}, },
@ -160,7 +169,6 @@
this.process = tab.name; this.process = tab.name;
this.listQuery.step__process = tab.name; this.listQuery.step__process = tab.name;
this.getList(); this.getList();
}, },
//操作记录删除 //操作记录删除

View File

@ -10,7 +10,23 @@
>查看作业指导书 >查看作业指导书
</el-button> </el-button>
</div> </div>
<el-form <el-descriptions :column="3" border style="margin-bottom: 20px">
<el-descriptions-item label="任务编号" v-if="operationData.number">{{operationData.number}}</el-descriptions-item>
<el-descriptions-item label="产品名称" v-if="operationData.name">{{operationData.name}}</el-descriptions-item>
<el-descriptions-item label="规格型号" v-if="operationData.specification">{{operationData.specification}}</el-descriptions-item>
<el-descriptions-item label="子工序">{{operationData.step_.name}}</el-descriptions-item>
<el-descriptions-item label="创建时间">{{operationData.create_time}}</el-descriptions-item>
<el-descriptions-item label="操作人">{{operationData.user}}</el-descriptions-item>
</el-descriptions>
<el-button
v-if="operationData.is_submited == false"
type="primary"
style="float: right"
@click="handlesubmit()"
>
提交本次操作
</el-button>
<!-- <el-form
ref="form" ref="form"
inline="true" inline="true"
:model="operationData" :model="operationData"
@ -22,6 +38,24 @@
disabled="disabled" disabled="disabled"
></el-input> ></el-input>
</el-form-item> </el-form-item>
<el-form-item label="任务编号" v-show="operationData.number">
<el-input
v-model="operationData.number"
disabled="disabled"
></el-input>
</el-form-item>
<el-form-item label="产品名称" v-show="operationData.name">
<el-input
v-model="operationData.name"
disabled="disabled"
></el-input>
</el-form-item>
<el-form-item label="规格型号" v-show="operationData.specification">
<el-input
v-model="operationData.specification"
disabled="disabled"
></el-input>
</el-form-item>
<el-form-item label="操作人"> <el-form-item label="操作人">
<el-input <el-input
v-model="operationData.user" v-model="operationData.user"
@ -35,16 +69,9 @@
></el-input> ></el-input>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button
v-if="operationData.is_submited == false"
type="primary"
style="float: right"
@click="handlesubmit()"
>
提交本次操作
</el-button>
</el-form-item> </el-form-item>
<!-- &lt;!&ndash;
<el-form-item label="边角料"> <el-form-item label="边角料">
<el-radio-group v-model="operationData.use_scrap"> <el-radio-group v-model="operationData.use_scrap">
<el-radio border <el-radio border
@ -58,7 +85,7 @@
<el-form-item label="备注" v-if="operationData.use_scrap"> <el-form-item label="备注" v-if="operationData.use_scrap">
<el-input type="textarea" v-model="operationData.remark"></el-input> <el-input type="textarea" v-model="operationData.remark"></el-input>
</el-form-item> </el-form-item>
!--> !&ndash;&gt;
<el-form-item v-if="operationData.use_scrap"> <el-form-item v-if="operationData.use_scrap">
<el-button <el-button
type="primary" type="primary"
@ -68,7 +95,7 @@
</el-button> </el-button>
<el-button>取消</el-button> <el-button>取消</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>-->
<el-drawer <el-drawer
title="作业指导书查看!" title="作业指导书查看!"
:visible.sync="drawer" :visible.sync="drawer"
@ -249,11 +276,16 @@
<el-table-column align="center" label="操作" width="100px"> <el-table-column align="center" label="操作" width="100px">
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
v-if="checkPermission(['warehouse_update'])"
type="primary" type="primary"
@click="handlerecord(scope)" @click="handlerecord(scope)"
>填写表单 >填写表单
</el-link> </el-link>
<el-link
v-if="scope.row.is_filled"
type="primary"
@click="handlerecordExport(scope)"
>导出
</el-link>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -647,7 +679,6 @@
.word-wrap { .word-wrap {
padding: 25px; padding: 25px;
} }
.box-card { .box-card {
height: 300px; height: 300px;
} }
@ -669,22 +700,20 @@
deleteOperationequip, deleteOperationequip,
deleteOperationwproduct, deleteOperationwproduct,
gettoolList, gettoolList,
createTool,
createInputs, createInputs,
recordInit, recordInit,
createOutputs, createOutputs,
deleteOperationeinput, deleteOperationeinput,
wproductPlace, wproductPlace,
} from "@/api/wpm"; } from "@/api/wpm";
import mammoth from "mammoth"; import { gettechdocList} from "@/api/mtm";
import {getrffieldList, gettechdocList} from "@/api/mtm";
import checkPermission from "@/utils/permission"; import checkPermission from "@/utils/permission";
import {getprogressList} from "@/api/pm"; import {getprogressList} from "@/api/pm";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination import {getTestRecordExport} from "@/api/qm";
import faceLogin from '@/components/faceLogin/review.vue'; import faceLogin from '@/components/faceLogin/review.vue';
export default { export default {
components: {Pagination, faceLogin}, components: {faceLogin},
inject: ["reload"], inject: ["reload"],
data() { data() {
return { return {
@ -811,9 +840,8 @@
pdf: "", pdf: "",
}; };
}, },
computed: {},
watch: {}, mounted() {
created() {
this.id = this.$route.params.id; //操作ID this.id = this.$route.params.id; //操作ID
this.readbook(); this.readbook();
this.getList(); //边角料 this.getList(); //边角料
@ -826,6 +854,7 @@
this.getprogressList(); //产出物料调出 this.getprogressList(); //产出物料调出
this.gettoolList(); //工序工装 this.gettoolList(); //工序工装
}, },
methods: { methods: {
checkPermission, checkPermission,
@ -890,6 +919,18 @@
getoperation(this.id).then((response) => { getoperation(this.id).then((response) => {
if (response.data) { if (response.data) {
this.operationData = response.data; this.operationData = response.data;
let names = '';
let numbers = '';
let specification = '';
response.data.out_detail.forEach(item=>{
names +=item.product.name;
numbers +=item.plan.number;
specification +=item.product.specification;
});
this.operationData.number = numbers;
this.operationData.name = names;
this.operationData.specification = specification;
if (response.data.is_submited) { if (response.data.is_submited) {
this.operationData.user = response.data.create_by_.name; this.operationData.user = response.data.create_by_.name;
} else { } else {
@ -991,13 +1032,23 @@
this.formID = scope.row.id; this.formID = scope.row.id;
recordInit(this.formID).then((response) => { recordInit(this.formID).then((response) => {
if (response.data) { if (response.data) {
debugger;
this.fieldList = response.data; this.fieldList = response.data;
this.fieldList.name = response.data.form_.name; this.fieldList.name = response.data.form_.name;
} }
}); });
this.dialogVisibleForm = true; this.dialogVisibleForm = true;
}, },
handlerecordExport(scope){
let exportFormId = scope.row.id;
getTestRecordExport(exportFormId).then(res=>{
if(res.code===200){
let link = document.createElement('a');
link.href = res.data.path;
document.body.appendChild(link);
link.click();
}
})
},
//工序工装列表 //工序工装列表
gettoolList() { gettoolList() {
@ -1208,9 +1259,10 @@
getMsgFormSon(data) { getMsgFormSon(data) {
let that = this; let that = this;
that.operationData.user = data.name; that.operationData.user = data.name;
let text = '确定以操作员'+data.name+'身份提交?';
if (data.token !== '' && data.token !== null && data.token !== undefined) { if (data.token !== '' && data.token !== null && data.token !== undefined) {
if (that.inputData == "") { if (that.inputData == "") {
that.$confirm("没有消耗物料确定提交吗?", "提示", { that.$confirm("没有消耗物料"+text, "提示", {
confirmButtonText: "确认", confirmButtonText: "确认",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "error", type: "error",
@ -1229,6 +1281,12 @@
that.limitedPhoto = false; that.limitedPhoto = false;
}); });
} else { } else {
this.$confirm(text, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
that.limitedPhoto = false;
submitOperation(that.id,{token:data.token}).then((res) => { submitOperation(that.id,{token:data.token}).then((res) => {
if (res.code === 200) { if (res.code === 200) {
that.$router.push({name: "operation"}); that.$router.push({name: "operation"});
@ -1239,6 +1297,10 @@
}).catch((err) => { }).catch((err) => {
that.$message.error(err); that.$message.error(err);
}); });
}).catch(() => {
that.limitedPhoto = false;
});
} }
} }
}, },

View File

@ -9,8 +9,9 @@
border border
fit fit
stripe stripe
height="100"
highlight-current-row highlight-current-row
max-height="600" v-el-height-adaptive-table="{bottomOffset: 60}"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="成品名称"> <el-table-column label="成品名称">
@ -53,7 +54,6 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination <pagination
v-show="wproductList.count > 0"
:total="wproductList.count" :total="wproductList.count"
:page.sync="listQuery.page" :page.sync="listQuery.page"
:limit.sync="listQuery.page_size" :limit.sync="listQuery.page_size"
@ -73,8 +73,9 @@
border border
fit fit
stripe stripe
height="100"
highlight-current-row highlight-current-row
max-height="600" v-el-height-adaptive-table="{bottomOffset: 60}"
> >
<el-table-column type="selection" width="55"></el-table-column> <el-table-column type="selection" width="55"></el-table-column>
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
@ -91,6 +92,12 @@
{{ actstate_[scope.row.act_state] }} {{ actstate_[scope.row.act_state] }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="检验员">
<template slot-scope="scope">
<span v-if="scope.row.update_by_!==null">{{scope.row.update_by_.username}}</span>
<span v-else>{{scope.row.create_by_.username}}</span>
</template>
</el-table-column>
<el-table-column label="指派订单"> <el-table-column label="指派订单">
<template slot-scope="scope" v-if="scope.row.order_"> <template slot-scope="scope" v-if="scope.row.order_">
{{scope.row.order_.number }} {{scope.row.order_.number }}
@ -118,7 +125,6 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination <pagination
v-show="wproductList1.count > 0"
:total="wproductList1.count" :total="wproductList1.count"
:page.sync="listQuery1.page" :page.sync="listQuery1.page"
:limit.sync="listQuery1.page_size" :limit.sync="listQuery1.page_size"
@ -282,16 +288,27 @@
<el-button type="primary" @click="putins"> </el-button> <el-button type="primary" @click="putins"> </el-button>
</div> </div>
</el-dialog> </el-dialog>
<!--操作人员确认-->
<el-dialog :visible.sync="limitedPhoto" @close="closeCamera" id="loginFaceWrap">
<div style="font-size: 28px;color: #333333;text-align: center;font-weight: bold;">操作人员确认</div>
<div class="testTracking">
<faceLogin
v-if="limitedPhoto"
ref="faceTracking"
name="faceLogin"
@func="getMsgFormSon"
></faceLogin>
</div>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
// import {getOrderList} from "@/api/sam";
import checkPermission from "@/utils/permission"; import checkPermission from "@/utils/permission";
import {getWarehouseList} from "@/api/inm"; import {getWarehouseList} from "@/api/inm";
import { getrecordformList, getrffieldList} from "@/api/mtm"; import { getrecordformList, getrffieldList} from "@/api/mtm";
// import {genTree} from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
import customForm from "@/components/customForm/index"; import customForm from "@/components/customForm/index";
import faceLogin from '@/components/faceLogin/review.vue';
import { import {
getwproductList, getwproductList,
wproductTest, wproductTest,
@ -309,12 +326,12 @@
const defaultetestitem = {}; const defaultetestitem = {};
export default { export default {
components: {Pagination, customForm}, components: {Pagination, customForm,faceLogin},
data() { data() {
return { return {
testitem: defaultetestitem, testitem: defaultetestitem,
form: {remark: "", warehouse: ""}, form: {remark: "", warehouse: ""},
form1: {}, submitForm: {},
wproductList: { wproductList: {
count: 0, count: 0,
}, },
@ -366,11 +383,13 @@
recordList: [], recordList: [],
recordformList: [], recordformList: [],
recordform: null, recordform: null,
submitFormId: null,
fifo_detail: "", fifo_detail: "",
listQueryrecordform: { listQueryrecordform: {
page: 0, page: 0,
}, },
hasPicture: false, hasPicture: false,
limitedPhoto: false,
outerVisible: false, outerVisible: false,
innerVisible: false, innerVisible: false,
dialogFormVisible: false, dialogFormVisible: false,
@ -674,12 +693,12 @@
//记录提交检查项目 //记录提交检查项目
recordSubmit(value) { recordSubmit(value) {
let that = this; // let that = this;
let id = value.id; this.submitFormId = value.id;
let params = {}; this.submitForm.record_data = value.record_data;
params.record_data = value.record_data; this.submitForm.is_testok = value.is_testok;
params.is_testok = value.is_testok; this.limitedPhoto = true;
putTestRecordItem(id, params) /*putTestRecordItem(id, params)
.then((res) => { .then((res) => {
if (res.code >= 200) { if (res.code >= 200) {
subTestRecordItem(id, params).then((res) => { subTestRecordItem(id, params).then((res) => {
@ -698,7 +717,7 @@
}) })
.catch((err) => { .catch((err) => {
this.$message.error(err); this.$message.error(err);
}); });*/
}, },
//第一次保存提交检查项目 //第一次保存提交检查项目
@ -706,6 +725,55 @@
this.outerVisible = false; this.outerVisible = false;
this.innerVisible = false; this.innerVisible = false;
}, },
//获取人脸数据
getMsgFormSon(data) {
let that = this;
let text = '确定以操作员'+data.name+'身份提交?';
if (data.token !== '' && data.token !== null && data.token !== undefined) {
this.$confirm(text, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
that.limitedPhoto = false;
putTestRecordItem(this.submitFormId, that.submitForm)
.then((res) => {
if (res.code >= 200) {
subTestRecordItem(this.submitFormId, that.submitForm).then((res) => {
if (res.code >= 200) {
that.innerVisible = false;
that.limitedReview = false;
that.limitedCheckRecord = false;
this.getList();
this.getList1();
that.refreshRecord();
}
});
} else {
this.$message.error(res.msg);
}
})
.catch((err) => {
this.$message.error(err);
});
}).catch(() => {
that.limitedPhoto = false;
});
}
},
/*关闭相机*/
closeCamera() {
this.$refs.faceTracking.closeCamera();
let video = document.getElementById('video');
let stream = video.srcObject;
let tracks = stream.getTracks();
tracks.forEach(track => {
track.stop()
});
video.srcObject = null;
},
}, },
}; };
</script> </script>

View File

@ -1,5 +1,6 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-card>
<el-tabs v-model="activeName" @tab-click="handleClick" type="border-card"> <el-tabs v-model="activeName" @tab-click="handleClick" type="border-card">
<el-tab-pane <el-tab-pane
v-for="item in processOption" v-for="item in processOption"
@ -13,7 +14,7 @@
border border
stripe stripe
style="width: 100%" style="width: 100%"
height="250" :height="tableHeight"
highlight-current-row highlight-current-row
@current-change="handleCurrentChange" @current-change="handleCurrentChange"
> >
@ -66,6 +67,11 @@
{{ state_[scope.row.state] }} {{ state_[scope.row.state] }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="任务状态">
<template slot-scope="scope">
<span v-if="scope.row.production_plan_"> {{ state_[scope.row.production_plan_.state] }}</span>
</template>
</el-table-column>
<el-table-column label="领料状态" width="80"> <el-table-column label="领料状态" width="80">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.is_picked == false">未领料</el-tag> <el-tag v-if="scope.row.is_picked == false">未领料</el-tag>
@ -85,21 +91,21 @@
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
v-if="checkPermission(['wmaterial_pick'])&&!scope.row.is_picked" v-if="checkPermission(['wmaterial_pick'])&&!scope.row.is_picked&&scope.row.production_plan_.state!==70&&scope.row.production_plan_.state!==80"
type="success" type="success"
@click="handleNeed(scope)" @click="handleNeed(scope)"
> >
领料 领料
</el-link> </el-link>
<el-link <el-link
v-if="checkPermission(['wmaterial_pick'])&&scope.row.is_picked" v-if="checkPermission(['wmaterial_pick'])&&scope.row.is_picked&&scope.row.production_plan_.state!==70&&scope.row.production_plan_.state!==80"
type="success" type="success"
@click="handleNeed(scope)" @click="handleNeed(scope)"
> >
继续领料 继续领料
</el-link> </el-link>
<el-link <el-link
v-if="checkPermission(['wmaterial_pick'])" v-if="checkPermission(['wmaterial_pick'])&&scope.row.production_plan_.state!==70&&scope.row.production_plan_.state!==80"
type="primary" type="primary"
@click="handlepick(scope)" @click="handlepick(scope)"
> >
@ -115,6 +121,10 @@
:limit.sync="listQuery.page_size" :limit.sync="listQuery.page_size"
@pagination="subproductionplanList" @pagination="subproductionplanList"
/> />
</el-tab-pane>
</el-tabs>
</el-card>
<el-card>
<el-row :gutter="2"> <el-row :gutter="2">
<el-col :span="12"> <el-col :span="12">
<el-card class="box-card"> <el-card class="box-card">
@ -134,10 +144,10 @@
{{ item.name }} {{ item.name }}
</el-button> </el-button>
<el-button <el-button
v-if="checkPermission(['wmaterial_scrap'])" v-show="checkPermission(['wp_scrap'])&&activeName==1"
id="scrap" id="scrap"
type="primary" type="primary"
style="float: right; display: none" style="float: right;"
@click="handleScrapbcp()" @click="handleScrapbcp()"
> >
报废 报废
@ -155,41 +165,41 @@
fit fit
stripe stripe
style="width: 100%" style="width: 100%"
max-height="300" :height="secondTableHeight"
:data="wproductData" :data="wproductData"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
> >
<el-table-column type="selection" width="40"></el-table-column> <el-table-column type="selection" width="40"></el-table-column>
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="子计划编号" width="100" show-overflow-tooltip> <el-table-column label="子计划编号" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.number }}</template>> <template slot-scope="scope">{{ scope.row.number }}</template>>
<template slot-scope="scope"> <template slot-scope="scope">
{{scope.row.subproduction_plan_.number}} {{scope.row.subproduction_plan_.number}}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="玻璃编号" prop="number" width="100" show-overflow-tooltip> <el-table-column label="玻璃编号" prop="number" min-width="100" show-overflow-tooltip>
</el-table-column> </el-table-column>
<el-table-column label="玻璃状态" width="100" show-overflow-tooltip> <el-table-column label="玻璃状态" min-width="100" show-overflow-tooltip>
<template slot-scope="scope"> <template slot-scope="scope">
{{scope.row.material_.name}} {{scope.row.material_.name}}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="所在子工序" width="100" show-overflow-tooltip> <el-table-column label="所在子工序" min-width="100" show-overflow-tooltip>
<template slot-scope="scope"> <template slot-scope="scope">
{{scope.row.step_.name}} {{scope.row.step_.name}}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="进行状态" width="100" show-overflow-tooltip> <el-table-column label="进行状态" min-width="100" show-overflow-tooltip>
<template slot-scope="scope"> <template slot-scope="scope">
{{actstate_[scope.row.act_state]}} {{actstate_[scope.row.act_state]}}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="不合格标记" width="100"> <el-table-column label="不合格标记" min-width="100">
<template slot-scope="scope"> <template slot-scope="scope">
{{ ng_sign_[scope.row.ng_sign] }} {{ ng_sign_[scope.row.ng_sign] }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="更新时间" prop="update_time" width="160"> <el-table-column label="更新时间" prop="update_time" min-width="160">
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-card> </el-card>
@ -205,7 +215,7 @@
fit fit
stripe stripe
style="width: 100%" style="width: 100%"
max-height="300" :height="tableHeight"
> >
<el-table-column type="index" width="50"/> <el-table-column type="index" width="50"/>
<el-table-column label="子计划编号" min-width="100" show-overflow-tooltip> <el-table-column label="子计划编号" min-width="100" show-overflow-tooltip>
@ -231,8 +241,7 @@
</el-card> </el-card>
</el-col> </el-col>
</el-row> </el-row>
</el-tab-pane> </el-card>
</el-tabs>
<el-dialog <el-dialog
title="半成品报废" title="半成品报废"
:close-on-click-modal="false" :close-on-click-modal="false"
@ -774,14 +783,16 @@
}, },
state_: { state_: {
0: "制定中", 10: "制定中",
1: "已下达", 20: "已下达",
2: "已接受", 30: "已接受",
3: "生产中", 40: "生产中",
4: "已完成", 50: "已完成",
60: "军检完成",
70: "暂停",
80: "终止",
}, },
listLoading: true, listLoading: true,
listLoading: true,
id: "", id: "",
dialogTableVisible: false, dialogTableVisible: false,
dialogVisible: false, dialogVisible: false,
@ -828,6 +839,8 @@
{lable: "其他", value: 40}, {lable: "其他", value: 40},
], ],
count: null, count: null,
tableHeight: null,
secondTableHeight: null,
}; };
}, },
process: "", process: "",
@ -841,29 +854,25 @@
//选项卡切换 //选项卡切换
handleClick(tab) { handleClick(tab) {
this.process = tab.name; let that = this;
this.listQuery.process = tab.name; that.process = tab.name;
if (tab.name == 1) { that.listQuery.process = tab.name;
document.getElementById("scrap").style.display = "block"; that.steps = [];
} getsubplanList(that.listQuery).then((response) => {
this.steps = [];
getsubplanList(this.listQuery).then((response) => {
if (response.data) { if (response.data) {
this.subproductionplanList = response.data; that.subproductionplanList = response.data;
} }
}); });
//子工序列表 //子工序列表
getStepLists(tab.name).then((response) => { getStepLists(tab.name).then((response) => {
if (response.data) { if (response.data) {
this.steps = response.data; that.steps = response.data;
} }
}); });
//车间物料表 //车间物料表
this.getwmaterialLists(); that.getwmaterialLists();
// 半成品表 // 半成品表
this.getwproductLists(); that.getwproductLists();
}, },
//车间物料 //车间物料
@ -900,7 +909,6 @@
//工序对应的子计划弹出对应的车间物料 //工序对应的子计划弹出对应的车间物料
handleCurrentChange(row) { handleCurrentChange(row) {
// this.steps = row.steps; //调出子工序 // this.steps = row.steps; //调出子工序
this.subproduction_plan = row.id; //子计划Id this.subproduction_plan = row.id; //子计划Id
this.getwproductLists(); this.getwproductLists();
getwmaterialList({ getwmaterialList({
@ -915,9 +923,29 @@
}, },
//大工序工序渲染 //大工序工序渲染
getProcessList() { getProcessList() {
let that = this;
getProcessList({page: 0}).then((response) => { getProcessList({page: 0}).then((response) => {
if (response.data) { if (response.data) {
this.processOption = response.data; that.processOption = response.data;
that.activeName = response.data[0].id;
that.process = response.data[0].id;
that.listQuery.process = response.data[0].id;
that.steps = [];
getsubplanList(that.listQuery).then((response) => {
if (response.data) {
that.subproductionplanList = response.data;
}
});
//子工序列表
getStepLists(response.data[0].id).then((response) => {
if (response.data) {
that.steps = response.data;
}
});
//车间物料表
that.getwmaterialLists();
// 半成品表
that.getwproductLists();
} }
}); });
}, },
@ -1013,9 +1041,7 @@
createPick(this.pickData).then((res) => { createPick(this.pickData).then((res) => {
if (res.code >= 200) { if (res.code >= 200) {
this.dialogVisiblenw = false; this.dialogVisiblenw = false;
this.$message.success("领料成功!"); this.$message.success("领料成功!");
this.listQuery.process = this.process; this.listQuery.process = this.process;
getsubplanList(this.listQuery).then((response) => { getsubplanList(this.listQuery).then((response) => {
@ -1174,5 +1200,11 @@
}); });
}, },
}, },
mounted() {
let H = document.getElementsByClassName('app-main')[0].clientHeight;
let h = H/2-85;
this.tableHeight = h+'px';
this.secondTableHeight = h-36+'px';
}
}; };
</script> </script>

View File

@ -25,12 +25,14 @@ class CleanDataView(APIView):
""" """
Order.objects.all().delete(soft=False) Order.objects.all().delete(soft=False)
ProductionPlan.objects.all().delete(soft=False) ProductionPlan.objects.all().delete(soft=False)
FIFO.objects.all().delete(soft=False) FIFO.objects.all().delete()
Material.objects.filter(type__in=[Material.MA_TYPE_GOOD, Material.MA_TYPE_HALFGOOD]).update(count=0) Material.objects.filter(type__in=[Material.MA_TYPE_GOOD, Material.MA_TYPE_HALFGOOD]).update(count=0)
MaterialBatch.objects.filter(material__type__in=[Material.MA_TYPE_GOOD, Material.MA_TYPE_HALFGOOD]).delete() MaterialBatch.objects.filter(material__type__in=[Material.MA_TYPE_GOOD, Material.MA_TYPE_HALFGOOD]).delete()
Inventory.objects.filter(material__type__in=[Material.MA_TYPE_GOOD, Material.MA_TYPE_HALFGOOD]).delete() Inventory.objects.filter(material__type__in=[Material.MA_TYPE_GOOD, Material.MA_TYPE_HALFGOOD]).delete()
Ticket.objects.all().delete(soft=False) Ticket.objects.all().delete(soft=False)
Operation.objects.all().delete() Operation.objects.all().delete()
from apps.pum.models import PuOrder
PuOrder.objects.all().delete(soft=False)
return Response() return Response()

View File

@ -20,10 +20,15 @@ class EmployeeNotWorkRemarkSerializer(ModelSerializer):
fields = ['not_work_remark'] fields = ['not_work_remark']
class FaceLoginSerializer(serializers.Serializer): class FaceLoginSerializer(serializers.Serializer):
base64 = serializers.CharField() base64 = serializers.CharField()
tolerance = serializers.FloatField(required=False, default=0.36)
class FaceLoginPathSerializer(serializers.Serializer):
path = serializers.CharField()
tolerance = serializers.FloatField(required=False, default=0.36)
class FaceClockCreateSerializer(serializers.Serializer): class FaceClockCreateSerializer(serializers.Serializer):
base64 = serializers.CharField() base64 = serializers.CharField()
tolerance = serializers.FloatField(required=False, default=0.36)
class ClockRecordListSerializer(serializers.ModelSerializer): class ClockRecordListSerializer(serializers.ModelSerializer):
create_by_ = UserSimpleSerializer(source='create_by', read_only=True) create_by_ = UserSimpleSerializer(source='create_by', read_only=True)

View File

@ -10,7 +10,40 @@ from django.core.cache import cache
class HRMService: class HRMService:
@classmethod @classmethod
def face_compare_from_base64(cls, base64_data): def face_compare_from_path(cls, path, tolerance=0.36):
filepath = settings.BASE_DIR +path
try:
unknown_picture = face_recognition.load_image_file(filepath)
unknown_face_encoding = face_recognition.face_encodings(unknown_picture, num_jitters=2)[0]
# os.remove(filepath)
except:
# os.remove(filepath)
return None, '识别失败,请调整位置'
# 匹配人脸库
face_datas = cache.get('face_datas')
if face_datas is None:
update_all_user_facedata_cache()
face_datas = cache.get('face_datas')
face_users = cache.get('face_users')
results = face_recognition.compare_faces(face_datas,
unknown_face_encoding, tolerance=tolerance)
user_index = cls.get_user_index(results)
user_index_len = len(user_index)
if user_index_len == 1:
user = User.objects.get(id=face_users[user_index[0]])
return user, ''
elif user_index_len == 0:
return None, '人脸未匹配,请调整位置'
else:
user_ids = []
for i in user_index:
user_ids.append(face_users[i])
user_name_str = ','.join(list(User.objects.filter(id__in=user_ids).values_list('name', flat=True)))
return None, '匹配多张人脸:' + user_name_str
@classmethod
def face_compare_from_base64(cls, base64_data, tolerance=0.36):
filename = str(uuid.uuid4()) filename = str(uuid.uuid4())
filepath = settings.BASE_DIR +'/temp/' + filename +'.png' filepath = settings.BASE_DIR +'/temp/' + filename +'.png'
with open(filepath, 'wb') as f: with open(filepath, 'wb') as f:
@ -30,13 +63,34 @@ class HRMService:
face_datas = cache.get('face_datas') face_datas = cache.get('face_datas')
face_users = cache.get('face_users') face_users = cache.get('face_users')
results = face_recognition.compare_faces(face_datas, results = face_recognition.compare_faces(face_datas,
unknown_face_encoding, tolerance=0.45) unknown_face_encoding, tolerance=tolerance)
user_index = cls.get_user_index(results)
user_index_len = len(user_index)
if user_index_len == 1:
user = User.objects.get(id=face_users[user_index[0]])
return user, ''
elif user_index_len == 0:
return None, '人脸未匹配,请调整位置'
else:
user_ids = []
for i in user_index:
user_ids.append(face_users[i])
user_name_str = ','.join(list(User.objects.filter(id__in=user_ids).values_list('name', flat=True)))
return None, '匹配多张人脸:' + user_name_str
@classmethod
def get_user_index(cls, results):
"""
返回user_index列表
"""
true_num = 0
user_index = []
for index, value in enumerate(results): for index, value in enumerate(results):
if value: if value:
# 识别成功 true_num = true_num + 1
user = User.objects.get(id=face_users[index]) user_index.append(index)
return user, '' return user_index
return None, '人脸未匹配,请调整位置'
@classmethod @classmethod
def get_facedata_from_img(cls, img_path): def get_facedata_from_img(cls, img_path):

View File

@ -18,7 +18,7 @@ def update_all_user_facedata_cache():
更新人脸数据缓存 更新人脸数据缓存
""" """
facedata_queyset = Employee.objects.filter(face_data__isnull=False, facedata_queyset = Employee.objects.filter(face_data__isnull=False,
user__is_active=True).values('user', 'face_data') user__is_active=True, user__is_deleted = False).values('user', 'face_data')
face_users = [] face_users = []
face_datas = [] face_datas = []
for i in facedata_queyset: for i in facedata_queyset:

View File

@ -1,6 +1,6 @@
from rest_framework import urlpatterns from rest_framework import urlpatterns
from apps.hrm.views import ClockRecordViewSet, EmployeeViewSet, FaceLogin, NotWorkRemarkViewSet from apps.hrm.views import ClockRecordViewSet, EmployeeViewSet, FaceLogin, FacePathLogin, NotWorkRemarkViewSet
from django.urls import path, include from django.urls import path, include
from rest_framework.routers import DefaultRouter from rest_framework.routers import DefaultRouter
@ -10,6 +10,7 @@ router.register('clock_record', ClockRecordViewSet, basename='clock_record')
router.register('not_work_remark', NotWorkRemarkViewSet, basename='not_work_reamrk') router.register('not_work_remark', NotWorkRemarkViewSet, basename='not_work_reamrk')
urlpatterns = [ urlpatterns = [
path('facelogin/', FaceLogin.as_view()), path('facelogin/', FaceLogin.as_view()),
path('facelogin_path/', FacePathLogin.as_view()),
path('', include(router.urls)), path('', include(router.urls)),
] ]

View File

@ -10,7 +10,7 @@ from apps.hrm.services import HRMService
from apps.hrm.tasks import update_all_user_facedata_cache from apps.hrm.tasks import update_all_user_facedata_cache
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
from apps.hrm.models import ClockRecord, Employee, NotWorkRemark from apps.hrm.models import ClockRecord, Employee, NotWorkRemark
from apps.hrm.serializers import ClockRecordListSerializer, EmployeeNotWorkRemarkSerializer, EmployeeSerializer, FaceClockCreateSerializer, FaceLoginSerializer, NotWorkRemarkListSerializer from apps.hrm.serializers import ClockRecordListSerializer, EmployeeNotWorkRemarkSerializer, EmployeeSerializer, FaceClockCreateSerializer, FaceLoginPathSerializer, FaceLoginSerializer, NotWorkRemarkListSerializer
@ -106,12 +106,12 @@ class ClockRecordViewSet(CreateModelMixin, ListModelMixin, GenericViewSet):
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
now = timezone.now() now = timezone.now()
now_local = timezone.localtime() now_local = timezone.localtime()
if 8<=now_local.hour<=17: if 6<=now_local.hour<=17:
base64_data = base64.urlsafe_b64decode(tran64( base64_data = base64.urlsafe_b64decode(tran64(
request.data.get('base64').replace(' ', '+'))) request.data.get('base64').replace(' ', '+')))
user, msg = HRMService.face_compare_from_base64(base64_data) user, msg = HRMService.face_compare_from_base64(base64_data, request.data.get('tolerance', 0.36))
if user: if user:
ins, created = ClockRecord.objects.get_or_create( ClockRecord.objects.get_or_create(
create_by = user, create_time__hour__range = [8,18], create_by = user, create_time__hour__range = [8,18],
create_time__year=now_local.year, create_time__month=now_local.month, create_time__year=now_local.year, create_time__month=now_local.month,
create_time__day=now_local.day, create_time__day=now_local.day,
@ -120,9 +120,9 @@ class ClockRecordViewSet(CreateModelMixin, ListModelMixin, GenericViewSet):
'create_by':user, 'create_by':user,
'create_time':now 'create_time':now
}) })
if not created: # if not created:
ins.update_time = now # ins.update_time = now
ins.save() # ins.save()
# 设为在岗 # 设为在岗
Employee.objects.filter(user=user).update(is_atwork=True, last_check_time=now) Employee.objects.filter(user=user).update(is_atwork=True, last_check_time=now)
return Response(UserSimpleSerializer(instance=user).data) return Response(UserSimpleSerializer(instance=user).data)
@ -160,7 +160,45 @@ class FaceLogin(CreateAPIView):
人脸识别登录 人脸识别登录
""" """
base64_data = base64.urlsafe_b64decode(tran64(request.data.get('base64').replace(' ', '+'))) base64_data = base64.urlsafe_b64decode(tran64(request.data.get('base64').replace(' ', '+')))
user, msg = HRMService.face_compare_from_base64(base64_data) user, msg = HRMService.face_compare_from_base64(base64_data, request.data.get('tolerance', 0.36))
if user:
refresh = RefreshToken.for_user(user)
# 可设为在岗
now = timezone.now()
now_local = timezone.localtime()
if 8<=now_local.hour<=17:
ins, created = ClockRecord.objects.get_or_create(
create_by = user, create_time__hour__range = [8,18],
create_time__year=now_local.year, create_time__month=now_local.month,
create_time__day=now_local.day,
defaults={
'type':ClockRecord.ClOCK_WORK1,
'create_by':user,
'create_time':now
})
# 设为在岗
if created:
Employee.objects.filter(user=user).update(is_atwork=True, last_check_time=now)
return Response({
'refresh': str(refresh),
'access': str(refresh.access_token),
'username':user.username,
'name':user.name
})
return Response(msg, status=status.HTTP_400_BAD_REQUEST)
class FacePathLogin(CreateAPIView):
authentication_classes = []
permission_classes = []
serializer_class = FaceLoginPathSerializer
def create(self, request, *args, **kwargs):
"""
人脸识别登录-文件地址
"""
user, msg = HRMService.face_compare_from_path(request.data.get('path'), request.data.get('tolerance', 0.36))
if user: if user:
refresh = RefreshToken.for_user(user) refresh = RefreshToken.for_user(user)
# 可设为在岗 # 可设为在岗

View File

@ -82,8 +82,7 @@ class FIFOItemViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, Updat
""" """
出入库记录详情表 出入库记录详情表
""" """
perms_map = {'get': '*', 'post':'fifoitem_create', perms_map = {'*':'*'}
'put':'fifoitem_update', 'delete':'fifoitem_delete'}
queryset = FIFOItem.objects.select_related('material', 'fifo').prefetch_related('files').all() queryset = FIFOItem.objects.select_related('material', 'fifo').prefetch_related('files').all()
serializer_class = FIFOItemSerializer serializer_class = FIFOItemSerializer
filterset_fields = ['material', 'fifo', filterset_fields = ['material', 'fifo',

View File

@ -0,0 +1,23 @@
# Generated by Django 3.2.9 on 2022-04-19 03:09
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0049_auto_20220222_0944'),
]
operations = [
migrations.AddField(
model_name='recordform',
name='export_template',
field=models.CharField(blank=True, max_length=200, null=True, verbose_name='导出模板'),
),
migrations.AddField(
model_name='recordformfield',
name='span',
field=models.PositiveSmallIntegerField(default=12, verbose_name='span值'),
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 3.2.9 on 2022-04-27 02:36
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('system', '0004_auto_20220318_1705'),
('mtm', '0050_auto_20220419_1109'),
]
operations = [
migrations.AddField(
model_name='material',
name='file',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='system.file', verbose_name='文件'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.9 on 2022-06-06 05:15
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0051_material_file'),
]
operations = [
migrations.AddField(
model_name='material',
name='brand',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='牌号'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.9 on 2022-06-09 00:14
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0052_material_brand'),
]
operations = [
migrations.AlterField(
model_name='material',
name='unit',
field=models.CharField(default='', max_length=10, verbose_name='基准计量单位'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.9 on 2022-06-27 05:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0053_alter_material_unit'),
]
operations = [
migrations.AddField(
model_name='usedstep',
name='reuse_form',
field=models.BooleanField(default=True, verbose_name='复用上表'),
),
]

View File

@ -36,13 +36,15 @@ class Material(CommonAModel):
) )
name = models.CharField('物料名称', max_length=100) name = models.CharField('物料名称', max_length=100)
number = models.CharField('编号', max_length=100, unique=True) number = models.CharField('编号', max_length=100, unique=True)
brand = models.CharField('牌号', max_length=100, null=True, blank=True)
specification = models.CharField('型号', max_length=100, null=True, blank=True) specification = models.CharField('型号', max_length=100, null=True, blank=True)
type = models.PositiveSmallIntegerField('物料类型', choices= type_choices, default=1) type = models.PositiveSmallIntegerField('物料类型', choices= type_choices, default=1)
sort_str = models.CharField('排序字符', max_length=100, null=True, blank=True) sort_str = models.CharField('排序字符', max_length=100, null=True, blank=True)
unit = models.CharField('基准计量单位', choices=unit_choices, default='', max_length=10) unit = models.CharField('基准计量单位', default='', max_length=10)
count = models.PositiveIntegerField('物料库存总数', default=0) count = models.PositiveIntegerField('物料库存总数', default=0)
count_safe = models.PositiveIntegerField('安全库存总数', null=True, blank=True) count_safe = models.PositiveIntegerField('安全库存总数', null=True, blank=True)
piece_count = models.PositiveSmallIntegerField('单片玻璃数量', null=True, blank=True) piece_count = models.PositiveSmallIntegerField('单片玻璃数量', null=True, blank=True)
file = models.ForeignKey(File, verbose_name='文件', on_delete=models.SET_NULL, null=True, blank=True)
class Meta: class Meta:
verbose_name = '物料表' verbose_name = '物料表'
verbose_name_plural = verbose_name verbose_name_plural = verbose_name
@ -139,6 +141,7 @@ class RecordForm(CommonAModel):
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE, null=True, blank=True) material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE, null=True, blank=True)
enabled = models.BooleanField('是否启用', default=False) enabled = models.BooleanField('是否启用', default=False)
number = models.CharField('编号', null=True, blank=True, max_length=32) number = models.CharField('编号', null=True, blank=True, max_length=32)
export_template = models.CharField('导出模板', max_length=200, null=True, blank=True)
class Meta: class Meta:
verbose_name = '记录表格' verbose_name = '记录表格'
@ -212,7 +215,7 @@ class RecordFormField(CommonAModel):
parent = models.ForeignKey('self', verbose_name='', on_delete=models.CASCADE, null=True, blank=True) parent = models.ForeignKey('self', verbose_name='', on_delete=models.CASCADE, null=True, blank=True)
draw_template = models.CharField('绘图模板', max_length=200, null=True, blank=True) draw_template = models.CharField('绘图模板', max_length=200, null=True, blank=True)
span = models.PositiveSmallIntegerField('span值', default=12)
class Meta: class Meta:
verbose_name = '记录表格字段' verbose_name = '记录表格字段'
@ -263,6 +266,7 @@ class UsedStep(CommonADModel):
""" """
step = models.ForeignKey(Step, verbose_name='子工序', on_delete=models.CASCADE, related_name='usedstep') step = models.ForeignKey(Step, verbose_name='子工序', on_delete=models.CASCADE, related_name='usedstep')
need_test = models.BooleanField('工序内检验', default=False) need_test = models.BooleanField('工序内检验', default=False)
reuse_form = models.BooleanField('复用上表', default=True)
remark = models.TextField('生产备注', null=True, blank=True) remark = models.TextField('生产备注', null=True, blank=True)
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE, related_name='usedstep_subproduction') subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE, related_name='usedstep_subproduction')

View File

@ -8,12 +8,14 @@ from apps.system.serializers import FileSimpleSerializer, OrganizationSimpleSeri
class MaterialSerializer(DynamicFieldsSerializerMixin, serializers.ModelSerializer): class MaterialSerializer(DynamicFieldsSerializerMixin, serializers.ModelSerializer):
file_ = FileSimpleSerializer(source='file', read_only=True)
class Meta: class Meta:
model = Material model = Material
fields = '__all__' fields = '__all__'
class MaterialDetailSerializer(serializers.ModelSerializer): class MaterialDetailSerializer(serializers.ModelSerializer):
processes_ = serializers.SerializerMethodField() processes_ = serializers.SerializerMethodField()
file_ = FileSimpleSerializer(source='file', read_only=True)
class Meta: class Meta:
model = Material model = Material
fields = '__all__' fields = '__all__'
@ -44,7 +46,7 @@ class PackItemUpdateSerializer(serializers.ModelSerializer):
class MaterialSimpleSerializer(serializers.ModelSerializer): class MaterialSimpleSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Material model = Material
fields = ['id', 'name', 'number', 'unit','specification', 'type', 'count', 'count_safe'] fields = ['id', 'name', 'number', 'unit','specification', 'type', 'count', 'count_safe', 'brand']
class PackItemDetailSerializer(serializers.ModelSerializer): class PackItemDetailSerializer(serializers.ModelSerializer):
material_ = MaterialSimpleSerializer(source='material', read_only=True) material_ = MaterialSimpleSerializer(source='material', read_only=True)
@ -161,7 +163,7 @@ class UsedStepCreateSerializer(serializers.ModelSerializer):
""" """
class Meta: class Meta:
model = UsedStep model = UsedStep
fields = ['step', 'subproduction', 'remark', 'need_test'] fields = ['step', 'subproduction', 'remark', 'need_test', 'reuse_form']
class UsedStepUpdateSerializer(serializers.ModelSerializer): class UsedStepUpdateSerializer(serializers.ModelSerializer):
""" """
@ -169,7 +171,7 @@ class UsedStepUpdateSerializer(serializers.ModelSerializer):
""" """
class Meta: class Meta:
model = UsedStep model = UsedStep
fields = ['remark', 'need_test'] fields = ['remark', 'need_test', 'reuse_form']
class UsedStepListSerializer(serializers.ModelSerializer): class UsedStepListSerializer(serializers.ModelSerializer):
""" """
@ -209,10 +211,10 @@ class RecordFormSerializer(serializers.ModelSerializer):
class RecordFormCreateSerializer(serializers.ModelSerializer): class RecordFormCreateSerializer(serializers.ModelSerializer):
form = serializers.PrimaryKeyRelatedField( form = serializers.PrimaryKeyRelatedField(
queryset=RecordForm.objects.all(), label="复制表ID", required=False) queryset=RecordForm.objects.all(), label="复制表ID", required=False, write_only=True)
class Meta: class Meta:
model = RecordForm model = RecordForm
fields = ['name', 'type', 'step', 'material', 'number', 'enabled', 'form'] fields = ['name', 'type', 'step', 'material', 'number', 'enabled', 'form', 'export_template']
# def validate(self, attrs): # def validate(self, attrs):
@ -225,7 +227,7 @@ class RecordFormCreateSerializer(serializers.ModelSerializer):
class RecordFormUpdateSerializer(serializers.ModelSerializer): class RecordFormUpdateSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = RecordForm model = RecordForm
fields = ['name', 'type', 'number', 'enabled'] fields = ['name', 'type', 'number', 'enabled', 'export_template', 'material']
# def validate(self, attrs): # def validate(self, attrs):
# if attrs['enabled']: # if attrs['enabled']:
@ -278,7 +280,7 @@ class RecordFormFieldCreateSerializer(serializers.ModelSerializer):
class RecordFormFieldUpdateSerializer(serializers.ModelSerializer): class RecordFormFieldUpdateSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = RecordFormField model = RecordFormField
exclude = ['field_key'] fields = '__all__'
class RecordFormFieldSimpleSerializer(serializers.ModelSerializer): class RecordFormFieldSimpleSerializer(serializers.ModelSerializer):
class Meta: class Meta:

View File

@ -19,7 +19,7 @@ class MaterialViewSet(PageOrNot, CreateUpdateModelAMixin, ModelViewSet):
""" """
perms_map = {'get': '*', 'post': 'material_create', perms_map = {'get': '*', 'post': 'material_create',
'put': 'material_update', 'delete': 'material_delete'} 'put': 'material_update', 'delete': 'material_delete'}
queryset = Material.objects.all() queryset = Material.objects.select_related('file').all()
serializer_class = MaterialSerializer serializer_class = MaterialSerializer
search_fields = ['name', 'number'] search_fields = ['name', 'number']
filterset_class = MaterialFilterSet filterset_class = MaterialFilterSet
@ -35,8 +35,8 @@ class PackItemViewSet(CreateUpdateModelAMixin, ModelViewSet):
""" """
装箱项目-增删改查 装箱项目-增删改查
""" """
perms_map = {'get': '*', 'post': 'packitem_create', perms_map = {'get': '*', 'post': 'material_update',
'put': 'packitem_update', 'delete': 'packitem_delete'} 'put': 'material_update', 'delete': 'material_update'}
queryset = PackItem.objects.all() queryset = PackItem.objects.all()
serializer_class = PackItemSerializer serializer_class = PackItemSerializer
search_fields = ['name', 'number'] search_fields = ['name', 'number']
@ -64,7 +64,7 @@ class ProcessViewSet(PageOrNot, CreateUpdateModelAMixin, ModelViewSet):
ordering_fields = ['number'] ordering_fields = ['number']
ordering = ['number'] ordering = ['number']
@action(methods=['get'], detail=True, perms_map={'get':'process_update'}, pagination_class=None, serializer_class=StepDetailSerializer) @action(methods=['get'], detail=True, perms_map={'get':'*'}, pagination_class=None, serializer_class=StepDetailSerializer)
def steps(self, request, pk=None): def steps(self, request, pk=None):
""" """
工序下的子工序 工序下的子工序
@ -166,7 +166,7 @@ class UsedStepViewSet(OptimizationMixin, CreateModelMixin, DestroyModelMixin, Li
'put':'subproduction_update', 'delete':'subproduction_update'} 'put':'subproduction_update', 'delete':'subproduction_update'}
queryset = UsedStep.objects.all() queryset = UsedStep.objects.all()
filterset_fields = ['subproduction', 'step'] filterset_fields = ['subproduction', 'step']
ordering = ['step__sort', '-step__create_time'] ordering = ['step__number', 'step__create_time']
def get_serializer_class(self): def get_serializer_class(self):
if self.action =='create': if self.action =='create':
@ -179,12 +179,12 @@ class RecordFormViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet
""" """
记录表格增删改查 记录表格增删改查
""" """
perms_map = {'get':'*', 'post':'recordform_create', perms_map = {'get':'*', 'post':'*',
'put':'recordform_update', 'delete':'recordform_delete'} 'put':'*', 'delete':'*'}
queryset = RecordForm.objects.all() queryset = RecordForm.objects.all()
filterset_fields = ['step', 'type', 'material', 'number', 'enabled'] filterset_fields = ['step', 'type', 'material', 'number', 'enabled']
search_fields = ['name'] search_fields = ['name']
ordering='id' ordering=['id']
def get_serializer_class(self): def get_serializer_class(self):
@ -229,13 +229,13 @@ class RecordFormFieldViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelVi
""" """
表格字段表 增删改查 表格字段表 增删改查
""" """
perms_map = {'get':'*', 'post':'recordform_update', perms_map = {'get':'*', 'post':'*',
'put':'recordform_update', 'delete':'recordform_update'} 'put':'*', 'delete':'*'}
queryset = RecordFormField.objects.all() queryset = RecordFormField.objects.all()
filterset_fields = ['field_type', 'form'] filterset_fields = ['field_type', 'form']
search_fields = ['field_name', 'field_key'] search_fields = ['field_name', 'field_key']
ordering = 'sort' ordering = ['sort', 'create_time']
ordering_fields = ['sort', 'id'] ordering_fields = ['sort', 'create_time']
def get_serializer_class(self): def get_serializer_class(self):
if self.action =='create': if self.action =='create':

View File

@ -2,7 +2,6 @@ from apps.mtm.models import RecordForm
from apps.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress from apps.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress
from rest_framework import serializers from rest_framework import serializers
from apps.qm.models import TestRecord from apps.qm.models import TestRecord
from apps.qm.serializers import TestRecordShortSerializer
from apps.sam.serializers import OrderSerializer, OrderSimpleSerializer from apps.sam.serializers import OrderSerializer, OrderSimpleSerializer
from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer, RecordFormSimpleSerializer, SubProductionSimpleSerializer from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer, RecordFormSimpleSerializer, SubProductionSimpleSerializer
from apps.system.serializers import OrganizationSimpleSerializer, UserSimpleSerializer from apps.system.serializers import OrganizationSimpleSerializer, UserSimpleSerializer
@ -12,7 +11,7 @@ from utils.mixins import DynamicFieldsSerializerMixin
class ProductionPlanCreateFromOrderSerializer(serializers.ModelSerializer): class ProductionPlanCreateFromOrderSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = ProductionPlan model = ProductionPlan
fields = ['order', 'count', 'start_date', 'end_date'] fields = ['order', 'count', 'start_date', 'end_date', 'number']
class ProductionPlanSerializer(DynamicFieldsSerializerMixin, serializers.ModelSerializer): class ProductionPlanSerializer(DynamicFieldsSerializerMixin, serializers.ModelSerializer):
order_ = OrderSimpleSerializer(source='order', read_only=True) order_ = OrderSimpleSerializer(source='order', read_only=True)
@ -21,6 +20,11 @@ class ProductionPlanSerializer(DynamicFieldsSerializerMixin, serializers.ModelSe
model = ProductionPlan model = ProductionPlan
fields ='__all__' fields ='__all__'
class ProductionPlanSimpleSerializer(serializers.ModelSerializer):
class Meta:
model = ProductionPlan
fields = ['number', 'state']
class ResourceCalSerializer(serializers.Serializer): class ResourceCalSerializer(serializers.Serializer):
id = serializers.IntegerField(label='产品ID') id = serializers.IntegerField(label='产品ID')
count = serializers.IntegerField(label='生产数量') count = serializers.IntegerField(label='生产数量')
@ -37,6 +41,7 @@ class ResourceCalListSerializer(serializers.ListSerializer):
class SubProductionPlanListSerializer(DynamicFieldsSerializerMixin, serializers.ModelSerializer): class SubProductionPlanListSerializer(DynamicFieldsSerializerMixin, serializers.ModelSerializer):
workshop_ = OrganizationSimpleSerializer(source='workshop', read_only=True) workshop_ = OrganizationSimpleSerializer(source='workshop', read_only=True)
production_plan_ = ProductionPlanSimpleSerializer(source='production_plan', read_only=True)
process_ = ProcessSimpleSerializer(source='process', read_only=True) process_ = ProcessSimpleSerializer(source='process', read_only=True)
subproduction_ = SubProductionSimpleSerializer(source='subproduction', read_only=True) subproduction_ = SubProductionSimpleSerializer(source='subproduction', read_only=True)
product_ = MaterialSimpleSerializer(source='product', read_only=True) product_ = MaterialSimpleSerializer(source='product', read_only=True)
@ -44,8 +49,7 @@ class SubProductionPlanListSerializer(DynamicFieldsSerializerMixin, serializers.
leader_1_ = UserSimpleSerializer(source='leader_1', read_only=True) leader_1_ = UserSimpleSerializer(source='leader_1', read_only=True)
leader_2_ = UserSimpleSerializer(source='leader_2', read_only=True) leader_2_ = UserSimpleSerializer(source='leader_2', read_only=True)
leader_3_ = UserSimpleSerializer(source='leader_3', read_only=True) leader_3_ = UserSimpleSerializer(source='leader_3', read_only=True)
first_test_ = TestRecordShortSerializer(source='first_test', read_only=True) first_test_ = serializers.SerializerMethodField()
# first_test_ = serializers.SerializerMethodField()
class Meta: class Meta:
model=SubProductionPlan model=SubProductionPlan
fields = '__all__' fields = '__all__'
@ -53,10 +57,12 @@ class SubProductionPlanListSerializer(DynamicFieldsSerializerMixin, serializers.
def get_plan_product_(self, obj): def get_plan_product_(self, obj):
return MaterialSimpleSerializer(instance=obj.production_plan.product).data return MaterialSimpleSerializer(instance=obj.production_plan.product).data
# def get_first_test_(self, obj): def get_first_test_(self, obj):
# if obj.first_test: tr = obj.first_test
# return TestRecordShortSerializer(instance=obj.first_test).data if obj.first_test:
# return None return {'id':tr.id, 'is_submited':tr.is_submited}
return None
class SubProductionPlanUpdateSerializer(serializers.ModelSerializer): class SubProductionPlanUpdateSerializer(serializers.ModelSerializer):

View File

@ -71,7 +71,7 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel
pass pass
else: else:
raise APIException('排产数量错误') raise APIException('排产数量错误')
instance = serializer.save(create_by=request.user, product=order.product, number='JH'+ranstr(7)) instance = serializer.save(create_by=request.user, product=order.product)
updateOrderPlanedCount(instance.order) updateOrderPlanedCount(instance.order)
return Response() return Response()
@ -150,7 +150,7 @@ class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateMo
""" """
子生产计划-列表/修改 子生产计划-列表/修改
""" """
perms_map = {'get': '*', 'put':'subplan_update'} perms_map = {'get': '*', 'put':'*'}
queryset = SubProductionPlan.objects.select_related('process', queryset = SubProductionPlan.objects.select_related('process',
'workshop', 'subproduction', 'product', 'workshop', 'subproduction', 'product',
'production_plan__product', 'leader_1', 'leader_2', 'leader_3', 'first_test') 'production_plan__product', 'leader_1', 'leader_2', 'leader_3', 'first_test')
@ -176,7 +176,7 @@ class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateMo
serializer = SubProductionProgressSerializer(instance=obj.progress_subplan, many=True) serializer = SubProductionProgressSerializer(instance=obj.progress_subplan, many=True)
return Response(serializer.data) return Response(serializer.data)
@action(methods=['post'], detail=True, perms_map={'post':'subplan_issue'}, serializer_class=serializers.Serializer) @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=serializers.Serializer)
@transaction.atomic @transaction.atomic
def issue(self, request, pk=None): def issue(self, request, pk=None):
""" """
@ -193,7 +193,7 @@ class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateMo
return Response() return Response()
raise APIException('计划状态有误') raise APIException('计划状态有误')
@action(methods=['post'], detail=True, perms_map={'post':'subplan_start'}, serializer_class=serializers.Serializer) @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=serializers.Serializer)
def start(self, request, pk=None): def start(self, request, pk=None):
""" """
开始生产 开始生产

View File

@ -0,0 +1,40 @@
from docxtpl import DocxTemplate, InlineImage
from apps.qm.models import TestRecord
from apps.qm.serializers import TestRecordDetailSerializer
from server.settings import BASE_DIR
from utils.tools import ranstr
from docx.shared import Mm
from apps.mtm.models import RecordFormField
def exprot_test_record(tr:TestRecord, tm:str):
data = TestRecordDetailSerializer(instance=tr).data
doc = DocxTemplate(BASE_DIR + tm)
edata = {}
edata['formName'] = data['form_']['name']
edata['glassSpec'] = data['wproduct_']['material_']['specification'] if data['wproduct_'] else ''
edata['glassNum'] = data['wproduct_']['number'] if data['wproduct_'] else ''
edata['testDate'] = data['update_time'][0:11] if data['update_time'] else data['create_time'][0:11]
tester_s = data['update_by_']['signature'] if data['update_by_'] else data['create_by_']['signature']
if tester_s: # 签名
edata['tester'] = InlineImage(doc, BASE_DIR + tester_s, height=Mm(10))
for i in data['record_data']:
if i['field_type'] == str(RecordFormField.FIELD_DRAW):
edata[i['field_key']] = {
's': InlineImage(doc, BASE_DIR + i['field_value'], width=Mm(40)),
'm': InlineImage(doc, BASE_DIR + i['field_value'], width=Mm(60)),
'l': InlineImage(doc, BASE_DIR + i['field_value'], width=Mm(80)),
}
else:
edata[i['field_key']] = i['origin_value'] if 'origin_value' in i else ''
if i['field_value'] not in ['', None]:
edata[i['field_key']] = i['field_value']
# 开始生成word
doc.render(edata)
filename = edata['formName'] + '_' + ranstr(6)
path = '/media/export/' + filename + '.docx'
filepath = BASE_DIR + path
doc.save(filepath)
return path

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.9 on 2022-06-13 01:25
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('qm', '0028_alter_testrecord_fifo_item'),
]
operations = [
migrations.AlterField(
model_name='testrecord',
name='number',
field=models.CharField(blank=True, max_length=20, null=True, verbose_name='玻璃编号'),
),
]

View File

@ -72,6 +72,7 @@ class TestRecord(CommonADModel):
is_submited = models.BooleanField('是否提交', default=False) is_submited = models.BooleanField('是否提交', default=False)
is_midtesting = models.BooleanField('是否子工序检验中', default=False) is_midtesting = models.BooleanField('是否子工序检验中', default=False)
remark = models.TextField('备注', default='') remark = models.TextField('备注', default='')
number = models.CharField('玻璃编号', max_length=20, null=True, blank=True)
class TestRecordItem(CommonADModel): class TestRecordItem(CommonADModel):

View File

@ -1,7 +1,8 @@
from rest_framework import serializers from rest_framework import serializers
from apps.mtm.models import RecordForm, RecordFormField from apps.mtm.models import RecordForm, RecordFormField
from apps.mtm.serializers import RecordFormFieldSerializer, RecordFormSimpleSerializer from apps.mtm.serializers import RecordFormFieldSerializer, RecordFormSimpleSerializer
from apps.system.serializers import FileSimpleSerializer, UserSimpleSerializer from apps.system.serializers import FileSimpleSerializer, UserSimpleSerializer, UserStandardSerializer
from apps.wpm.serializers import WProductBaseSerializer
from .models import Standard, TestItem, TestRecord, TestRecordItem from .models import Standard, TestItem, TestRecord, TestRecordItem
from django.db import transaction from django.db import transaction
@ -97,8 +98,9 @@ class TestRecordDetailSerializer(serializers.ModelSerializer):
# record_data = TestRecordItemSerializer(source='item_test_record', read_only=True, many=True) # record_data = TestRecordItemSerializer(source='item_test_record', read_only=True, many=True)
record_data = serializers.SerializerMethodField() record_data = serializers.SerializerMethodField()
origin_test_ = TestRecordDetailBaseSerializer(source='origin_test', read_only=True) origin_test_ = TestRecordDetailBaseSerializer(source='origin_test', read_only=True)
create_by_ = UserSimpleSerializer(source='create_by', read_only=True) create_by_ = UserStandardSerializer(source='create_by', read_only=True)
update_by_ = UserSimpleSerializer(source='update_by', read_only=True) update_by_ = UserStandardSerializer(source='update_by', read_only=True)
wproduct_ = WProductBaseSerializer(source='wproduct', read_only=True)
class Meta: class Meta:
model = TestRecord model = TestRecord
fields = '__all__' fields = '__all__'
@ -127,7 +129,7 @@ class TestRecordUpdateSerializer(serializers.ModelSerializer):
record_data = TestRecordItemUpdatexSerializer(many=True, write_only=True) record_data = TestRecordItemUpdatexSerializer(many=True, write_only=True)
class Meta: class Meta:
model = TestRecord model = TestRecord
fields = ['is_testok', 'record_data'] fields = ['is_testok', 'record_data', 'number', 'remark']
def update(self, instance, validated_data): def update(self, instance, validated_data):
# 获取更新人 # 获取更新人

View File

@ -1,5 +1,7 @@
from rest_framework import exceptions, serializers from rest_framework import exceptions, serializers
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
from apps.mtm.models import RecordFormField
from apps.qm.export import exprot_test_record
from apps.qm.serializers import StandardCreateUpdateSerializer, StandardSerializer, TestItemCreateUpdateSerializer, TestItemSerializer, TestRecordCreateSerializer, TestRecordDetailSerializer, TestRecordListSerializer, TestRecordUpdateSerializer from apps.qm.serializers import StandardCreateUpdateSerializer, StandardSerializer, TestItemCreateUpdateSerializer, TestItemSerializer, TestRecordCreateSerializer, TestRecordDetailSerializer, TestRecordListSerializer, TestRecordUpdateSerializer
from apps.qm.models import Standard, TestItem, TestRecord, TestRecordItem from apps.qm.models import Standard, TestItem, TestRecord, TestRecordItem
from django.shortcuts import render from django.shortcuts import render
@ -13,6 +15,7 @@ from rest_framework.decorators import action
from apps.wpm.models import WProduct from apps.wpm.models import WProduct
from apps.wpm.services import WpmService from apps.wpm.services import WpmService
from rest_framework.exceptions import ParseError
# Create your views here. # Create your views here.
class StandardViewSet(CreateUpdateModelAMixin, ModelViewSet): class StandardViewSet(CreateUpdateModelAMixin, ModelViewSet):
""" """
@ -92,11 +95,25 @@ class TestRecordViewSet(ListModelMixin, UpdateModelMixin, RetrieveModelMixin, De
raise exceptions.APIException('存在未填写项目:'+ ','.join(list(items_not.values_list('form_field__field_name', flat=True)))) raise exceptions.APIException('存在未填写项目:'+ ','.join(list(items_not.values_list('form_field__field_name', flat=True))))
with transaction.atomic(): with transaction.atomic():
obj.is_submited=True obj.is_submited=True
obj.update_by = request.user
obj.save() obj.save()
if obj.wproduct: if obj.wproduct:
WpmService.update_wproduct_by_test(obj, request.user) # 这里已经做了日志记录和进度计算 WpmService.update_wproduct_by_test(obj, request.user) # 这里已经做了日志记录和进度计算
return Response() return Response()
@action(methods=['get'], detail=True, perms_map={'get':'*'}, serializer_class=serializers.Serializer)
def export(self, request, pk=None):
"""
按模板导出
"""
instance = self.get_object()
# tm = instance.form.export_template
tm = '/media/default/tmp.docx'
if tm:
path = exprot_test_record(tr=instance, tm=tm)
return Response({'path':path})
raise ParseError('未配置导出模板')
# def create(self, request, *args, **kwargs): # def create(self, request, *args, **kwargs):
# serializer = self.get_serializer(data=request.data) # serializer = self.get_serializer(data=request.data)
# serializer.is_valid(raise_exception=True) # serializer.is_valid(raise_exception=True)

View File

@ -43,10 +43,10 @@ class ContractCreateUpdateSerializer(serializers.ModelSerializer):
class OrderCreateUpdateSerializer(serializers.ModelSerializer): class OrderCreateUpdateSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Order model = Order
fields = ['customer', 'contract', 'product', 'count', 'delivery_date', 'need_mtest'] fields = ['customer', 'contract', 'product', 'count', 'delivery_date', 'need_mtest', 'number']
def create(self, validated_data): def create(self, validated_data):
validated_data['number'] = 'DD' + ranstr(7) # validated_data['number'] = 'DD' + ranstr(7)
return super().create(validated_data) return super().create(validated_data)
class OrderSerializer(DynamicFieldsSerializerMixin, serializers.ModelSerializer): class OrderSerializer(DynamicFieldsSerializerMixin, serializers.ModelSerializer):

View File

@ -130,7 +130,7 @@ class AtWorkCountView(CreateAPIView):
""" """
到岗天数统计 到岗天数统计
""" """
perms_map = {'get':'*'} perms_map = {'post':'*'}
serializer_class = AtWorkCountSerializer serializer_class = AtWorkCountSerializer
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):

View File

@ -8,7 +8,7 @@ def get_permission_list(user):
""" """
获取权限列表,可用redis存取 获取权限列表,可用redis存取
""" """
perms_list = ['visitor'] perms_list = []
if user.is_superuser: if user.is_superuser:
perms_list = ['admin'] perms_list = ['admin']
else: else:
@ -17,8 +17,12 @@ def get_permission_list(user):
if roles: if roles:
for i in roles: for i in roles:
perms = perms | i.perms.all() perms = perms | i.perms.all()
perms_list = perms.values_list('method', flat=True) perms_list_l = perms.values_list('method', flat=True)
perms_list = list(set(perms_list)) for i in perms_list_l:
if i and i not in perms_list:
perms_list.append(i)
if len(perms_list) == 0:
perms_list = ['visitor']
cache.set(user.username + '__perms', perms_list, 60*60) cache.set(user.username + '__perms', perms_list, 60*60)
return perms_list return perms_list
@ -35,6 +39,7 @@ class RbacPermission(BasePermission):
:param view: :param view:
:return: :return:
""" """
perms = ['visitor']
if not request.user: if not request.user:
if request.META.get('HTTP_AUTHORIZATION', None) == 'big_screen': if request.META.get('HTTP_AUTHORIZATION', None) == 'big_screen':
perms = ['visitor'] perms = ['visitor']

View File

@ -126,6 +126,16 @@ class UserSimpleSerializer(serializers.ModelSerializer):
model = User model = User
fields = ['id', 'username', 'name'] fields = ['id', 'username', 'name']
class UserStandardSerializer(serializers.ModelSerializer):
signature= serializers.SerializerMethodField()
class Meta:
model = User
fields = ['id', 'username', 'name', 'signature']
def get_signature(self, obj):
if hasattr(obj, 'employee_user'):
return obj.employee_user.signature
return None
# class UserStandardSerializer(serializers.ModelSerializer): # class UserStandardSerializer(serializers.ModelSerializer):
# dept_name = serializers.StringRelatedField(source='dept') # dept_name = serializers.StringRelatedField(source='dept')
# class Meta: # class Meta:

View File

@ -136,6 +136,13 @@ class WProduct(CommonAModel):
""" """
return self.test_wproduct.filter(type=TestRecord.TEST_PROCESS, is_submited=True).order_by('-id').first() return self.test_wproduct.filter(type=TestRecord.TEST_PROCESS, is_submited=True).order_by('-id').first()
@property
def last_wp_test(self):
"""
最后提交的本产品本工序自检
"""
return self.test_wproduct.filter(is_submited=True, type=TestRecord.TEST_PROCESS, subproduction_plan=self.subproduction_plan).order_by('-id').first()
class WprouctTicket(CommonAModel): class WprouctTicket(CommonAModel):
""" """

View File

@ -8,11 +8,11 @@ from apps.inm.serializers import WareHouseSimpleSerializer
from apps.inm.services import InmService from apps.inm.services import InmService
from apps.mtm.models import Material, RecordForm, RecordFormField, Step, SubprodctionMaterial from apps.mtm.models import Material, RecordForm, RecordFormField, Step, SubprodctionMaterial
from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer, RecordFormSimpleSerializer, StepSimpleSerializer from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer, RecordFormSimpleSerializer, StepSimpleSerializer
from django.db.models.aggregates import Sum, Count
from apps.pm.models import SubProductionPlan, SubProductionProgress from apps.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress
from django.utils import timezone from django.utils import timezone
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from apps.pm.serializers import SubproductionPlanSimpleSerializer from apps.pm.serializers import ProductionPlanSerializer, ProductionPlanSimpleSerializer, SubproductionPlanSimpleSerializer
from apps.qm.models import TestRecord, TestRecordItem from apps.qm.models import TestRecord, TestRecordItem
from apps.sam.serializers import OrderSimpleSerializer from apps.sam.serializers import OrderSimpleSerializer
from apps.system.models import User from apps.system.models import User
@ -168,6 +168,8 @@ class WProductListSerializer(DynamicFieldsSerializerMixin, serializers.ModelSeri
children = serializers.SerializerMethodField() children = serializers.SerializerMethodField()
to_order_ = OrderSimpleSerializer(source='to_order', read_only=True) to_order_ = OrderSimpleSerializer(source='to_order', read_only=True)
order_ = serializers.SerializerMethodField() order_ = serializers.SerializerMethodField()
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
update_by_ = UserSimpleSerializer(source='update_by', read_only=True)
class Meta: class Meta:
model = WProduct model = WProduct
fields = '__all__' fields = '__all__'
@ -242,6 +244,8 @@ class WProductDetailSerializer(serializers.ModelSerializer):
children = serializers.SerializerMethodField() children = serializers.SerializerMethodField()
to_order_ = OrderSimpleSerializer(source='to_order', read_only=True) to_order_ = OrderSimpleSerializer(source='to_order', read_only=True)
order_ = OrderSimpleSerializer(source='subproduction_plan__production_plan__order', read_only=True) order_ = OrderSimpleSerializer(source='subproduction_plan__production_plan__order', read_only=True)
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
update_by_ = UserSimpleSerializer(source='update_by', read_only=True)
class Meta: class Meta:
model = WProduct model = WProduct
fields = '__all__' fields = '__all__'
@ -254,18 +258,22 @@ class WProductDetailSerializer(serializers.ModelSerializer):
class OperationDetailSerializer(serializers.ModelSerializer): class OperationDetailSerializer(serializers.ModelSerializer):
create_by_ = UserSimpleSerializer(source='create_by', read_only=True) create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
update_by_ = UserSimpleSerializer(source='update_by', read_only=True)
step_ = StepSimpleSerializer(source='step', read_only=True) step_ = StepSimpleSerializer(source='step', read_only=True)
class Meta: class Meta:
model = Operation model = Operation
fields = '__all__' fields = '__all__'
class OperationListSerializer(serializers.ModelSerializer): class OperationListSerializer(serializers.ModelSerializer):
create_by_ = UserSimpleSerializer(source='create_by', read_only=True) create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
update_by_ = UserSimpleSerializer(source='update_by', read_only=True)
step_ = StepSimpleSerializer(source='step', read_only=True) step_ = StepSimpleSerializer(source='step', read_only=True)
out_detail = serializers.SerializerMethodField()
# wproduct_ = serializers.SerializerMethodField() # wproduct_ = serializers.SerializerMethodField()
count_work = serializers.SerializerMethodField() # count_work = serializers.SerializerMethodField()
equip_ = serializers.SerializerMethodField() # equip_ = serializers.SerializerMethodField()
record_ = serializers.SerializerMethodField() # record_ = serializers.SerializerMethodField()
class Meta: class Meta:
model = Operation model = Operation
fields = '__all__' fields = '__all__'
@ -273,8 +281,31 @@ class OperationListSerializer(serializers.ModelSerializer):
# def get_wproduct_(self, obj): # def get_wproduct_(self, obj):
# return WProduct.objects.filter(ow_wproduct__operation=obj).values('id', 'number') # return WProduct.objects.filter(ow_wproduct__operation=obj).values('id', 'number')
def get_out_detail(self, obj):
rets = []
if obj.step.type == Step.STEP_TYPE_NOM:
qs = OperationWproduct.objects.filter(operation=obj).values(
'subproduction_plan__production_plan',
'subproduction_plan__production_plan__product'
).annotate(count=Count('wproduct'))
else:
qs = OperationMaterial.objects.filter(operation=obj,
type=SubprodctionMaterial.SUB_MA_TYPE_OUT, subproduction_progress__is_main=True).values(
'subproduction_plan__production_plan',
'subproduction_plan__production_plan__product'
).annotate(count=Sum('count'))
for i in qs:
ret = {}
ret['plan'] = ProductionPlanSimpleSerializer(instance=ProductionPlan.objects.get(
id= i['subproduction_plan__production_plan'])).data
ret['product'] = MaterialSimpleSerializer(instance=Material.objects.get(
id=i['subproduction_plan__production_plan__product'])).data
ret['count'] = i['count']
rets.append(ret)
return rets
def get_count_work(self, obj): def get_count_work(self, obj):
from django.db.models.aggregates import Sum
count_work = 0 count_work = 0
if obj.step.type == Step.STEP_TYPE_NOM: if obj.step.type == Step.STEP_TYPE_NOM:
count_work = OperationWproduct.objects.filter(operation=obj).count() count_work = OperationWproduct.objects.filter(operation=obj).count()

View File

@ -2,28 +2,54 @@ from django.utils import timezone
from typing import List from typing import List
from django.db.models.expressions import F from django.db.models.expressions import F
from apps.mtm.serializers import UsedStepListSerializer
from apps.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress from apps.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress
from apps.mtm.models import Material, Step, SubprodctionMaterial from apps.mtm.models import Material, Step, SubprodctionMaterial, UsedStep
from apps.qm.models import TestRecord from apps.qm.models import TestRecord
from apps.system.models import User from apps.system.models import User
from apps.wf.models import State, TicketFlow, Transition from apps.wf.models import State, TicketFlow, Transition
from apps.wpm.models import Operation, OperationMaterial, WProduct, WproductFlow, WprouctTicket from apps.wpm.models import Operation, OperationMaterial, WProduct, WproductFlow, WprouctTicket
from utils.tools import ranstr from utils.tools import ranstr
from rest_framework.exceptions import ParseError
class WpmService(object): class WpmService(object):
@classmethod @classmethod
def get_next_step(cls, subproduction_plan:SubProductionPlan, nowstep:Step): def get_step_info(cls, subproduction_plan:SubProductionPlan, nowstep:Step):
""" """
获取下一步骤 返回下一步骤 当前步骤是否需要检验 当前步骤是否需要复用表
""" """
steps_list = subproduction_plan.steps used_steps = UsedStep.objects.filter(subproduction=subproduction_plan.subproduction).order_by('step__number')
stepIds = [i['id'] for i in steps_list] if nowstep is None:
pindex = stepIds.index(nowstep.id) try:
need_test = steps_list[pindex].get('need_test', False) nowstep = used_steps[0].step
if pindex + 1 < len(stepIds): except:
return Step.objects.get(pk=stepIds[pindex+1]), need_test pass
else: for index, i in enumerate(used_steps):
return nowstep, need_test if i.step == nowstep:
try:
used_step = used_steps[index+1]
return used_step.step, i.need_test, i.reuse_form
except:
return nowstep, i.need_test, i.reuse_form
raise ParseError('获取步骤信息失败')
# steps_list = subproduction_plan.steps
# stepIds = [i['id'] for i in steps_list]
# pindex = stepIds.index(nowstep.id)
# if get_next:
# if pindex + 1 < len(stepIds):
# pindex = pindex + 1
# need_test = steps_list[pindex].get('need_test', False)
# reuse_form = steps_list[pindex].get('reuse_form', True)
# return Step.objects.get(pk=stepIds[pindex]), need_test, reuse_form
# else:
# need_test = steps_list[pindex].get('need_test', False)
# reuse_form = steps_list[pindex].get('reuse_form', True)
# return nowstep, need_test, reuse_form
# else:
# need_test = steps_list[pindex].get('need_test', False)
# reuse_form = steps_list[pindex].get('reuse_form', True)
# return
@classmethod @classmethod
def get_subplans_queryset_from_wproducts(cls, wproducts:List): def get_subplans_queryset_from_wproducts(cls, wproducts:List):
@ -49,7 +75,6 @@ class WpmService(object):
""" """
is_testok = test.is_testok is_testok = test.is_testok
wproduct = test.wproduct wproduct = test.wproduct
test_i = None
if is_testok: if is_testok:
if wproduct.act_state == WProduct.WPR_ACT_STATE_TORETEST: # 复检 if wproduct.act_state == WProduct.WPR_ACT_STATE_TORETEST: # 复检
wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
@ -61,7 +86,6 @@ class WpmService(object):
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and \ elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and \
test.is_midtesting is True: test.is_midtesting is True:
wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
test_i = test
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and wproduct.material.type == Material.MA_TYPE_GOOD: # 成品检验 elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and wproduct.material.type == Material.MA_TYPE_GOOD: # 成品检验
wproduct.act_state = WProduct.WPR_ACT_STATE_TOFINALTEST wproduct.act_state = WProduct.WPR_ACT_STATE_TOFINALTEST
@ -70,7 +94,10 @@ class WpmService(object):
else: else:
wproduct.act_state = WProduct.WPR_ACT_STATE_OK wproduct.act_state = WProduct.WPR_ACT_STATE_OK
if wproduct.number is None: # 产生半成品编号 if wproduct.number is None: # 产生半成品编号
wproduct.number = 'WP'+ranstr(7) if test.number:
wproduct.number = test.number
else:
raise ParseError('请提供玻璃编号')
# 去除ng_sign # 去除ng_sign
if wproduct.ng_sign: if wproduct.ng_sign:
@ -108,7 +135,7 @@ class WpmService(object):
wproduct.update_by = user wproduct.update_by = user
wproduct.update_time = timezone.now() wproduct.update_time = timezone.now()
wproduct.test = test_i wproduct.test = None
wproduct.last_test_result = is_testok wproduct.last_test_result = is_testok
wproduct.save() wproduct.save()
# 添加日志 # 添加日志

View File

@ -4,14 +4,14 @@ from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, \
from rest_framework.viewsets import GenericViewSet from rest_framework.viewsets import GenericViewSet
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct
from apps.inm.services import InmService from apps.inm.services import InmService
from apps.mtm.models import Material, RecordForm, RecordFormField, Step, SubprodctionMaterial, TechDoc from apps.mtm.models import Material, RecordForm, RecordFormField, Step, SubprodctionMaterial, TechDoc, UsedStep
from apps.mtm.serializers import RecordFormDetailSerializer, SubprodctionMaterialListSerializer, TechDocListSerializer from apps.mtm.serializers import RecordFormDetailSerializer, SubprodctionMaterialListSerializer, TechDocListSerializer
from apps.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress from apps.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress
from apps.pm.serializers import SubProductionPlanListSerializer, SubProductionProgressSerializer from apps.pm.serializers import SubProductionPlanListSerializer, SubProductionProgressSerializer
from apps.qm.models import TestRecord, TestRecordItem from apps.qm.models import TestRecord, TestRecordItem
from apps.qm.serializers import TestRecordDetailSerializer from apps.qm.serializers import TestRecordDetailSerializer
from apps.system.mixins import CreateUpdateModelAMixin from apps.system.mixins import CreateUpdateCustomMixin, CreateUpdateModelAMixin
from rest_framework.decorators import action from rest_framework.decorators import action
from apps.wf.models import Workflow from apps.wf.models import Workflow
from apps.wpm.filters import CuttingFilterSet, OperationRecordFilterSet, WMaterialFilterSet, WProductFilterSet from apps.wpm.filters import CuttingFilterSet, OperationRecordFilterSet, WMaterialFilterSet, WProductFilterSet
@ -36,7 +36,7 @@ from apps.wpm.services import WpmService
from django.utils import timezone from django.utils import timezone
from rest_framework import status from rest_framework import status
from django.db.models import Count, Q from django.db.models import Count, Q
from rest_framework.exceptions import ParseError
from utils.tools import ranstr from utils.tools import ranstr
@ -49,11 +49,7 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
""" """
perms_map = {'get': '*'} perms_map = {'get': '*'}
queryset = SubProductionPlan.objects.select_related( queryset = SubProductionPlan.objects.select_related(
'process', 'workshop', 'subproduction', 'product').filter( 'process', 'workshop', 'subproduction', 'product', 'production_plan').exclude(state=SubProductionPlan.SUBPLAN_STATE_PLANING)
production_plan__state__in =[
ProductionPlan.PLAN_STATE_WORKING, ProductionPlan.PLAN_STATE_ASSGINED
]
)
search_fields = [] search_fields = []
serializer_class = SubProductionPlanListSerializer serializer_class = SubProductionPlanListSerializer
filterset_fields = ['production_plan', filterset_fields = ['production_plan',
@ -160,7 +156,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
perms_map = {'get': '*'} perms_map = {'get': '*'}
queryset = WProduct.objects.select_related('step', 'material', queryset = WProduct.objects.select_related('step', 'material',
'subproduction_plan', 'warehouse', 'subproduction_plan__production_plan__order', 'subproduction_plan', 'warehouse', 'subproduction_plan__production_plan__order',
'to_order').prefetch_related('wp_child') 'to_order', 'update_by', 'create_by').prefetch_related('wp_child')
serializer_class = WProductListSerializer serializer_class = WProductListSerializer
filterset_class = WProductFilterSet filterset_class = WProductFilterSet
search_fields = ['number', 'material__name', 'subproduction_plan__number'] search_fields = ['number', 'material__name', 'subproduction_plan__number']
@ -189,14 +185,14 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
vdata = serializer.validated_data vdata = serializer.validated_data
wproduct = vdata['wproduct'] wproduct = vdata['wproduct']
form = vdata['form'] form = vdata['form']
if wproduct.test:
raise exceptions.APIException('存在进行中检验')
# 根据情况创建一条检验记录 # 根据情况创建一条检验记录
if wproduct.act_state not in [WProduct.WPR_ACT_STATE_TOTEST, if wproduct.act_state not in [WProduct.WPR_ACT_STATE_TOTEST,
WProduct.WPR_ACT_STATE_TORETEST, WProduct.WPR_ACT_STATE_TOFINALTEST, WProduct.WPR_ACT_STATE_TORETEST, WProduct.WPR_ACT_STATE_TOFINALTEST,
WProduct.WPR_ACT_STATE_TOCOMBTEST]: WProduct.WPR_ACT_STATE_TOCOMBTEST]:
raise exceptions.APIException('该产品当前状态不可检验') raise exceptions.APIException('该产品当前状态不可检验')
if wproduct.test:
raise exceptions.APIException('存在进行中检验')
savedict = dict( savedict = dict(
create_by=request.user, create_by=request.user,
wproduct=wproduct, wproduct=wproduct,
@ -206,7 +202,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
step=wproduct.step, step=wproduct.step,
form=form) form=form)
if wproduct.act_state == WProduct.WPR_ACT_STATE_TORETEST: if wproduct.act_state == WProduct.WPR_ACT_STATE_TORETEST:
# 查找最近一条检验记录 # 查找最近一条工序检验记录
trs = wproduct.last_process_test trs = wproduct.last_process_test
savedict['origin_test'] = trs savedict['origin_test'] = trs
if not trs: if not trs:
@ -216,9 +212,11 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
savedict['type'] = TestRecord.TEST_FINAL savedict['type'] = TestRecord.TEST_FINAL
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOCOMBTEST: elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOCOMBTEST:
savedict['type'] = TestRecord.TEST_COMB savedict['type'] = TestRecord.TEST_COMB
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and\ elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST:
wproduct.step != wproduct.pre_step: # 如果是工序内检验 _, need_test, _ = WpmService.get_step_info(wproduct.subproduction_plan, wproduct.pre_step)
if need_test and wproduct.step != wproduct.pre_step:
savedict['is_midtesting'] = True savedict['is_midtesting'] = True
# if UsedStep.objects.filter(subproduction=wproduct.subproduction_plan.subproduction).first().need_test:
tr = TestRecord.objects.create(**savedict) tr = TestRecord.objects.create(**savedict)
# 更新wproduct # 更新wproduct
wproduct.test = tr wproduct.test = tr
@ -439,7 +437,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
WpmService.add_wproduct_flow_log(instance=obj, change_str=change_str) WpmService.add_wproduct_flow_log(instance=obj, change_str=change_str)
return Response() return Response()
@action(methods=['get'], detail=True, perms_map={'get': 'wp_card'}) @action(methods=['get'], detail=True, perms_map={'get': '*'})
def card(self, request, pk=None): def card(self, request, pk=None):
""" """
流程卡 流程卡
@ -530,19 +528,16 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
""" """
perms_map = {'get': '*', 'post':'operation_create', perms_map = {'get': '*', 'post':'operation_create',
'put':'operation_update', 'delete':'operation_delete'} 'put':'operation_update', 'delete':'operation_delete'}
queryset = Operation.objects.select_related('step').prefetch_related( queryset = Operation.objects.select_related('step', 'create_by', 'update_by').prefetch_related(
'ow_operation', 'oe_operation', 'or_operation').all() 'ow_operation', 'oe_operation', 'or_operation').all()
serializer_class = OperationListSerializer serializer_class = OperationListSerializer
filterset_fields = ['step', 'step__process', 'is_submited'] filterset_fields = ['step', 'step__process', 'is_submited']
ordering_fields = ['id'] ordering_fields = ['id']
ordering = ['-id'] ordering = ['-id']
def get_queryset(self):
return self.queryset.filter(create_by=self.request.user)
def get_serializer_class(self): def get_serializer_class(self):
if self.action == 'retrieve': if self.action == 'retrieve':
return OperationDetailSerializer return OperationListSerializer
elif self.action == 'create': elif self.action == 'create':
return OperationCreateSerializer return OperationCreateSerializer
elif self.action == 'update': elif self.action == 'update':
@ -608,6 +603,11 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
# 查询需要填写的自定义表格 # 查询需要填写的自定义表格
forms = RecordForm.objects.filter( forms = RecordForm.objects.filter(
step=step, type=RecordForm.RF_TYPE_DO, enabled=True) step=step, type=RecordForm.RF_TYPE_DO, enabled=True)
# 根据产品不同进行筛选 这里其实是有问题的,应该是以产出物归属产品来查表,但操作刚创建是没有的,先这样吧
if 'wproducts' in vdata and splans:
xforms = forms.filter(material=splans[0].production_plan.product)
if xforms.exists():
forms = xforms
for i in forms: for i in forms:
opr = OperationRecord() opr = OperationRecord()
opr.operation = op opr.operation = op
@ -637,7 +637,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
opm.material = i.material opm.material = i.material
opm.type = SubprodctionMaterial.SUB_MA_TYPE_TOOL opm.type = SubprodctionMaterial.SUB_MA_TYPE_TOOL
opm.save() opm.save()
return Response() return Response(OperationListSerializer(instance=op).data)
@action(methods=['post'], detail=True, perms_map={'post': 'operation_submit'}, serializer_class=serializers.Serializer) @action(methods=['post'], detail=True, perms_map={'post': 'operation_submit'}, serializer_class=serializers.Serializer)
@transaction.atomic @transaction.atomic
@ -700,24 +700,32 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
wsp = i.subproduction_plan wsp = i.subproduction_plan
# 获取下一步子工序 # 获取下一步子工序
newstep, needTest = WpmService.get_next_step(wsp, step) newstep, needTest, reuseForm = WpmService.get_step_info(wsp, step)
wp.step = newstep wp.step = newstep
wp.pre_step = step wp.pre_step = step
wp.material = wsp.product wp.material = wsp.product
if step == newstep: if step == newstep:
wp.act_state = WProduct.WPR_ACT_STATE_TOTEST wp.act_state = WProduct.WPR_ACT_STATE_TOTEST
if wp.test:# 如果有正在进行的工序中检验 last_test = wp.last_wp_test
wp.test.is_midtesting = False if last_test and reuseForm:
wp.test.is_submited = False last_test.is_midtesting = False
wp.test.save() last_test.is_submited = False
last_test.save()
wp.test = last_test
wp.save()
else: else:
wp.act_state = WProduct.WPR_ACT_STATE_DOWAIT wp.act_state = WProduct.WPR_ACT_STATE_DOWAIT
if needTest: if needTest: #子工序若需要检验
print(needTest, reuseForm)
wp.act_state = WProduct.WPR_ACT_STATE_TOTEST wp.act_state = WProduct.WPR_ACT_STATE_TOTEST
if wp.test:# 如果有正在进行的工序中检验 last_test = wp.last_wp_test
wp.test.is_submited = False if last_test and reuseForm:
wp.test.save() last_test.is_midtesting = True
last_test.is_submited = False
last_test.save()
wp.test = last_test
wp.save()
wp.operation = None wp.operation = None
wp.update_by = request.user wp.update_by = request.user
@ -734,7 +742,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
raise exceptions.APIException('请选择物料产出') raise exceptions.APIException('请选择物料产出')
for i in omos: for i in omos:
if i.subproduction_progress.is_main: if i.subproduction_progress.is_main:
newstep, _ = WpmService.get_next_step( newstep, _, _ = WpmService.get_step_info(
i.subproduction_plan, step) i.subproduction_plan, step)
wpr = dict(material=i.material, step=newstep, wpr = dict(material=i.material, step=newstep,
act_state=WProduct.WPR_ACT_STATE_DOWAIT, remark='', act_state=WProduct.WPR_ACT_STATE_DOWAIT, remark='',
@ -755,7 +763,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
if oms_w.count!=1: if oms_w.count!=1:
raise exceptions.APIException('产出数量应为1') raise exceptions.APIException('产出数量应为1')
# 校验单片数量是否正确, 暂时未写 # 校验单片数量是否正确, 暂时未写
newstep, needTest = WpmService.get_next_step( newstep, needTest, reuseForm = WpmService.get_step_info(
oms_w.subproduction_plan, step) oms_w.subproduction_plan, step)
wproduct = WProduct() wproduct = WProduct()
wproduct.material = oms_w.material wproduct.material = oms_w.material
@ -763,14 +771,24 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
wproduct.subproduction_plan = oms_w.subproduction_plan wproduct.subproduction_plan = oms_w.subproduction_plan
if step == newstep: if step == newstep:
wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST
if wproduct.test:# 如果有正在进行的工序中检验 last_test = wproduct.last_wp_test
wproduct.test.is_midtesting = False if last_test and reuseForm:
wproduct.test.is_submited = False last_test.is_midtesting = False
wproduct.test.save() last_test.is_submited = False
last_test.save()
wproduct.test = last_test
wproduct.save()
else: else:
wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
if needTest: if needTest:
wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST
last_test = wproduct.last_wp_test
if last_test and reuseForm:
last_test.is_midtesting = True
last_test.is_submited = False
last_test.save()
wproduct.test = last_test
wproduct.save()
# 更新子计划进度 # 更新子计划进度
WpmService.update_subproduction_progress_main( WpmService.update_subproduction_progress_main(
@ -787,6 +805,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
else: else:
raise exceptions.APIException('产出物料未填写或填写错误') raise exceptions.APIException('产出物料未填写或填写错误')
op.is_submited = True op.is_submited = True
op.update_by = request.user
op.save() op.save()
# 如果是冷加工 # 如果是冷加工
@ -800,7 +819,7 @@ class OperationWproductViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMix
操作使用的半成品 操作使用的半成品
""" """
perms_map = {'get': '*', 'post':'operation_update', perms_map = {'get': '*', 'post':'operation_update',
'put':'operation_update', 'delete':'operation_delete'} 'put':'operation_update', 'delete':'operation_update'}
queryset = OperationWproduct.objects.select_related( queryset = OperationWproduct.objects.select_related(
'subproduction_plan', 'material').all() 'subproduction_plan', 'material').all()
serializer_class = OperationWproductListSerializer serializer_class = OperationWproductListSerializer
@ -831,7 +850,7 @@ class OperationEquipViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin,
操作使用的设备 操作使用的设备
""" """
perms_map = {'get': '*', 'post':'operation_update', perms_map = {'get': '*', 'post':'operation_update',
'put':'operation_update', 'delete':'operation_delete'} 'put':'operation_update', 'delete':'operation_update'}
queryset = OperationEquip.objects.select_related( queryset = OperationEquip.objects.select_related(
'operation', 'equip').all() 'operation', 'equip').all()
serializer_class = OperationEquipListSerializer serializer_class = OperationEquipListSerializer
@ -864,7 +883,7 @@ class OperationRecordViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin
操作使用的自定义表格 操作使用的自定义表格
""" """
perms_map = {'get': '*', 'post':'operation_update', perms_map = {'get': '*', 'post':'operation_update',
'put':'operation_update', 'delete':'operation_delete'} 'put':'operation_update', 'delete':'operation_update'}
queryset = OperationRecord.objects.select_related( queryset = OperationRecord.objects.select_related(
'operation', 'form').all() 'operation', 'form').all()
serializer_class = OperationRecordListSerializer serializer_class = OperationRecordListSerializer
@ -908,7 +927,7 @@ class OperationMaterialInputViewSet(ListModelMixin, CreateModelMixin, DestroyMod
""" """
消耗物料 消耗物料
""" """
perms_map = {'get': '*', 'post':'operation_update', 'delete':'operation_delete'} perms_map = {'get': '*', 'post':'operation_update', 'delete':'operation_update'}
queryset = OperationMaterial.objects.select_related( queryset = OperationMaterial.objects.select_related(
'operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_IN) 'operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_IN)
serializer_class = OperationMaterialListSerializer serializer_class = OperationMaterialListSerializer
@ -960,7 +979,7 @@ class OperationMaterialOutputViewSet(ListModelMixin, CreateModelMixin, DestroyMo
""" """
产出物料 产出物料
""" """
perms_map = {'get': '*', 'post':'operation_update', 'delete':'operation_delete'} perms_map = {'get': '*', 'post':'operation_update', 'delete':'operation_update'}
queryset = OperationMaterial.objects.select_related( queryset = OperationMaterial.objects.select_related(
'operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_OUT) 'operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
serializer_class = OperationMaterialListSerializer serializer_class = OperationMaterialListSerializer
@ -997,7 +1016,7 @@ class OperationMaterialToolViewSet(ListModelMixin, CreateModelMixin, DestroyMode
""" """
工具工装 工具工装
""" """
perms_map = {'get': '*', 'post':'operation_update', 'delete':'operation_delete'} perms_map = {'get': '*', 'post':'operation_update', 'delete':'operation_update'}
queryset = OperationMaterial.objects.select_related( queryset = OperationMaterial.objects.select_related(
'operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_TOOL) 'operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_TOOL)
serializer_class = OperationMaterialListSerializer serializer_class = OperationMaterialListSerializer

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Some files were not shown because too many files have changed in this diff Show More