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'
# 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://127.0.0.1:8000/api'

View File

@ -29,7 +29,11 @@
"element-ui": "^2.15.5",
"file-saver": "^2.0.2",
"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",
"jspdf": "^2.5.1",
"mammoth": "^1.4.19",
"normalize.css": "^8.0.1",
"nprogress": "0.2.0",

View File

@ -65,6 +65,13 @@ export function getTestRecord(query) {
params: query
})
}
//检测记录模板
export function getTestRecordExport(id) {
return request({
url: `/qm/testrecord/${id}/export/`,
method: 'get'
})
}
//检测记录
export function getTestRecordItem(id) {
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() {
return request({
url: '/auth/token/black/',

View File

@ -3,7 +3,7 @@
<el-form
id="customerForm"
ref="checkForm"
label-width="100px"
label-width="150px"
:model="checkForm"
>
<el-row>
@ -32,8 +32,8 @@
required
>
<el-input-number
style="width: 100%;"
v-model="checkForm[item.field_key]"
style="width: 100%;"
step-strictly
placeholder="请输入"
:min="0"
@ -46,8 +46,8 @@
required
>
<el-input-number
style="width: 100%;"
v-model="checkForm[item.field_key]"
style="width: 100%;"
:precision="2"
:step="0.1"
placeholder="请输入"
@ -133,7 +133,7 @@
<el-row v-show="hasPicture">
<el-form-item label="图表">
<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;
border: 1px solid #DCDFE6;">
<canvas id="canvas" width="500" height="300">
@ -158,8 +158,18 @@
<el-radio v-model="is_testok" :label="testokTrue">检查合格</el-radio>
<el-radio v-model="is_testok" :label="testokFalse">检查不合格</el-radio>
</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">
<el-button @click="recordCancel"> </el-button>
<el-button @click="recordCancel"> </el-button>
<el-button type="primary" @click="submitfield('1')">保存</el-button>
<el-button type="warning" @click="submitfield('2')">提交</el-button>
</div>
@ -169,65 +179,75 @@
</template>
<script>
import { upFile } from "@/api/file";
import {upFile} from "@/api/file";
let preDrawAry = [];
export default {
name: "index",
props: {
results:{
type:Array,
results: {
type: Array,
default: () => {
return []
}} ,
}
},
formID: {
type:Number,
default:0
type: Number,
default: 0
},
wproduct: {
type:Number,
default:0
type: Number,
default: 0
},
recordId: {
type:Number,
default:null
type: Number,
default: null
},
hasPicture:{
type:Boolean,
default:false
hasPicture: {
type: Boolean,
default: false
},
isDisabled: {
type: Boolean,
default: false
},
numbers: {
type: String,
default: ''
},
remark:{
type: String,
default: ''
},
isDisabled:{
type:Boolean,
default:false
}
},
mounted() {
let that = this;
that.checkForm = {};
this.form = this.formID;
let formData=this.results;
that.wproductId=this.wproduct;
let formData = this.results;
that.wproductId = this.wproduct;
formData.forEach(item => {
let obj = new Object();
obj = item;
if(item.field_type === 'draw'){
if (item.field_type === 'draw') {
obj.is_testok = true;
}else{
} else {
obj.is_testok = null;
}
that.formData.push(obj)
});
that.formData=[...formData];
for(let i=0;i<this.results.length;i++){
that.formData = [...formData];
for (let i = 0; i < this.results.length; i++) {
let key = this.results[i].field_key;
//checkForm接收表单数据的对象
let valu = this.results[i].field_value;
if(valu!==null&&valu!==''&&valu!==undefined){
that.checkForm[key]=valu;
that.$set(that.checkForm,key,valu);
if (valu !== null && valu !== '' && valu !== undefined) {
that.checkForm[key] = valu;
that.$set(that.checkForm, key, valu);
that.is_save = true;
}else{
that.checkForm[key]='';
that.$set(that.checkForm,key,null)
} else {
that.checkForm[key] = '';
that.$set(that.checkForm, key, '')
}
}
let listJudge = this.formData.filter(item => {
@ -238,172 +258,176 @@
obj = item;
that.judgeList.push(obj)
});
let imag= this.formData.filter(item => {
let imag = this.formData.filter(item => {
return item.field_type === 'draw';
});
if(imag.length>0){
if (imag.length > 0) {
that.img = new Image();
that.img.crossOrigin = 'anonymous';
let value = imag[0].field_value?imag[0].field_value:imag[0].draw_template;
that.img = 'http://49.232.14.174:2222'+value;
setTimeout(function(){
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 =process.env.VUE_APP_BASE_API.replace('/api','')+ value;
setTimeout(function () {
that.canvasInit();
},500);
}, 1000);
}
},
data(){
return{
field:[],
checkForm:{},
testrecord:{
form:this.formID,
record_data:[],
is_testok:true,
wproduct:null,
data() {
return {
field: [],
checkForm: {},
testrecord: {
form: this.formID,
record_data: [],
is_testok: true,
wproduct: null,
},
canvas:null,
wproductId:null,
ctx:null,
myCanvas_rect:null,
Txt:null,
word:null,
img:null,
widths:0,
heights:0,
lineW:3,
colorF:"#e42343",
imgUrl:'',
imgData:'',
canvasImg:'',
formData:[],//表单数组
judgeList:[],//判定数组
is_testok:true,
testokTrue:true,
is_save:false,
require:false,
testokFalse:false,
canvas: null,
wproductId: null,
ctx: null,
myCanvas_rect: null,
Txt: null,
word: null,
img: null,
widths: 0,
heights: 0,
lineW: 3,
colorF: "#e42343",
imgUrl: '',
imgData: '',
canvasImg: '',
formData: [],//表单数组
judgeList: [],//判定数组
is_testok: true,
testokTrue: true,
is_save: false,
require: false,
testokFalse: false,
index: '1',
}
},
methods:{
filterBlock(rule,index,field_key){
methods: {
checkValue() {
this.numbers = this.numbers.replace(/[^0-9a-zA-Z]/g, '');
},
filterBlock(rule, index, field_key) {
let that = this;
if(rule!==''&&rule!==null&&rule!==undefined){
if (rule !== '' && rule !== null && rule !== undefined) {
let reg = /\{(.+?)\}/g;
if(rule.indexOf('||')>-1||rule.indexOf('&&')>-1){
if (rule.indexOf('||') > -1 || rule.indexOf('&&') > -1) {
let tam = '', arr = [];
if(rule.indexOf('||')>-1){
if (rule.indexOf('||') > -1) {
arr = rule.split('||');
}else{
} else {
arr = rule.split('&&');
}
for (let i = 0;i<arr.length;i++){
for (let i = 0; i < arr.length; i++) {
//获取判断依据
let a = '';
a = arr[i].replace(/`/g,'');
a = '`'+ a+'`';
let tem =a.match(reg)[0];
a = arr[i].replace(/`/g, '');
a = '`' + a + '`';
let tem = a.match(reg)[0];
let ky = tem.replace(/\{|\}/g, '');//qipao
if(that.checkForm[ky]){
if (that.checkForm[ky]) {
//替换变量
a = a.replace(ky, 'yyy');
let yyy = "'"+that.checkForm[ky]+"'";
if(eval(eval( a))){
let yyy = "'" + that.checkForm[ky] + "'";
if (eval(eval(a))) {
tam += 'true';
}else{
} else {
tam += 'false';
}
}else{
} else {
tam += 'false';
}
}
let rea = true;
if(rule.indexOf('||')>-1){
if( tam.indexOf('true')>-1){
if (rule.indexOf('||') > -1) {
if (tam.indexOf('true') > -1) {
rea = true;
}else{
} else {
rea = false;
}
}else{
if( tam.indexOf('false')>-1){
} else {
if (tam.indexOf('false') > -1) {
rea = false;
}else{
} else {
rea = true;
}
}
if(rea){
if (rea) {
that.formData[index].is_hidden = false;
}else{
} else {
that.formData[index].is_hidden = true;
that.checkForm[field_key] = null;
that.checkForm[field_key] = '';
}
return rea;
}else{
let temp =rule.match(reg)[0];
} else {
let temp = rule.match(reg)[0];
let key = temp.replace(/\{|\}/g, '');//qipao
let a = rule.replace(key, 'yy');
let a = rule.replace(key, 'yy');
a = a.replace(key, 'yy');
let yy = "'"+that.checkForm[key]+"'";
if(eval(eval(a))){
let yy = "'" + that.checkForm[key] + "'";
if (eval(eval(a))) {
that.formData[index].is_hidden = false;
}else{
} else {
that.formData[index].is_hidden = true;
that.checkForm[field_key] = null;
that.checkForm[field_key] = '';
}
return eval(eval(a));
}
}else{
} else {
that.formData[index].is_hidden = false;
return true;
}
},
keyChange(index,key){
keyChange(index, key) {
let that = this;
let reg = /\{(.+?)\}/g;
that.$forceUpdate();
that.$nextTick(()=>{
if(that.formData[index].need_judge===true){
let arr = [],str = '';
let item = that.formData[index].rule_expression.replace(/`/g,'');
if(item.indexOf('||')>-1){
that.$nextTick(() => {
if (that.formData[index].need_judge === true) {
let arr = [], str = '';
let item = that.formData[index].rule_expression.replace(/`/g, '');
if (item.indexOf('||') > -1) {
arr = item.split('||');
}else if(item.indexOf('&&')>-1){
} else if (item.indexOf('&&') > -1) {
arr = item.split('&&');
}else{
} else {
arr.push(item);
}
//对每个条件进行判定如果符合
for (let i = 0;i<arr.length;i++){
for (let i = 0; i < arr.length; i++) {
//获取判断依据
let a = '`'+ arr[i]+'`';
let tem =a.match(reg)[0];
let a = '`' + arr[i] + '`';
let tem = a.match(reg)[0];
let ky = tem.replace(/\{|\}/g, '');//qipao
//有值时进行判断
if(that.checkForm[ky]!==''&&that.checkForm[ky]!==null&&that.checkForm[ky]!==undefined){
if (that.checkForm[ky] !== '' && that.checkForm[ky] !== null && that.checkForm[ky] !== undefined) {
//替换变量
a = a.replace(ky, 'yyy');
let yyy = "'"+that.checkForm[ky]+"'";
if(eval(eval( a))){
let yyy = "'" + that.checkForm[ky] + "'";
if (eval(eval(a))) {
str += 'true';
}else{
} else {
str += 'false';
}
}
}
if(item.indexOf('&&')>-1){
if(str.indexOf('false')>-1){
if (item.indexOf('&&') > -1) {
if (str.indexOf('false') > -1) {
that.formData[index].is_testok = true;
that.$set(that.formData[index],'is_testok',true)
}else{
that.$set(that.formData[index], 'is_testok', true)
} else {
that.formData[index].is_testok = false;
that.$set(that.formData[index],'is_testok',false)
that.$set(that.formData[index], 'is_testok', false)
}
}else{
if(str.indexOf('true')>-1){
} else {
if (str.indexOf('true') > -1) {
that.formData[index].is_testok = false;
that.$set(that.formData[index],'is_testok',false)
}else{
that.$set(that.formData[index], 'is_testok', false)
} else {
that.formData[index].is_testok = true;
that.$set(that.formData[index],'is_testok',true)
that.$set(that.formData[index], 'is_testok', true)
}
}
that.$forceUpdate();
@ -417,7 +441,7 @@
},
/* 图片保存 */
//初始化canvas
canvasInit(){
canvasInit() {
let that = this;
preDrawAry = [];
that.canvas = document.getElementById('canvas');
@ -427,55 +451,54 @@
that.word = document.getElementById('word');
that.widths = that.myCanvas_rect.width;
that.heights = that.myCanvas_rect.height;
setTimeout(function(){
setTimeout(function () {
that.draw();
},500);
}, 500);
},
//画布添加背景模板图
draw(){
draw() {
this.ctx = document.getElementById('canvas').getContext('2d');
let canvasImg = document.getElementById("canvasImg");
canvasImg.setAttribute("crossOrigin",'anonymous');
canvasImg.style.width = '500px';
canvasImg.style.height = '300px';
this.ctx.drawImage(canvasImg,0,0,500,300);
// canvasImg.setAttribute("crossOrigin", 'anonymous');
this.ctx.drawImage(canvasImg, 0, 0, 500, 300);
},
// 叉号
error1(){
error1() {
let canvas1 = document.getElementById('canvas');
let ctx1 = canvas1.getContext('2d');
this.Txt.style.display="none";
document.getElementById('word').style.display="none";
this.Txt.style.display = "none";
document.getElementById('word').style.display = "none";
ctx1.closePath();
canvas1.onmousedown=function () {
this.imgData= ctx1.getImageData(0,0,canvas1.width,canvas1.height);
canvas1.onmousedown = function () {
this.imgData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height);
preDrawAry.push(this.imgData);
ctx1.beginPath();
ctx1.strokeStyle = "#e42343";
ctx1.lineWidth = "3";
ctx1.lineJoin="round";
ctx1.lineJoin = "round";
};
//鼠标按下的位置
canvas1.onmouseup=function (ev) {
canvas1.onmouseup = function (ev) {
let oldX = ev.offsetX;
let oldY = ev.offsetY;
ctx1.moveTo(oldX,oldY);
ctx1.lineTo(ev.offsetX+10,ev.offsetY+10);
ctx1.moveTo(ev.offsetX+10,ev.offsetY);
ctx1.lineTo(ev.offsetX,ev.offsetY+10);
ctx1.moveTo(oldX, oldY);
ctx1.lineTo(ev.offsetX + 10, ev.offsetY + 10);
ctx1.moveTo(ev.offsetX + 10, ev.offsetY);
ctx1.lineTo(ev.offsetX, ev.offsetY + 10);
ctx1.stroke();
};
this.ctx.closePath();
},
// 文字先写字
text(){
text() {
let canvas2 = document.getElementById('canvas');
let ctx2 = canvas2.getContext('2d');
let Txt2 = document.getElementById('txt');
Txt2.style.display="block";
document.getElementById('word').style.display="none";
ctx2.font="16px Microsoft Yahei";
canvas2.onmousedown=function (ev) {
this.imgData=ctx2.getImageData(0,0,canvas2.width,canvas2.height);
Txt2.style.display = "block";
document.getElementById('word').style.display = "none";
ctx2.font = "16px Microsoft Yahei";
canvas2.onmousedown = function (ev) {
this.imgData = ctx2.getImageData(0, 0, canvas2.width, canvas2.height);
preDrawAry.push(this.imgData);
var v = Txt2.value;
// console.log(v);
@ -483,63 +506,63 @@
var oldX = ev.offsetX;
var oldY = ev.offsetY;
// console.log(oldX,oldY);
ctx2.moveTo(oldX,oldY);
canvas2.onmouseup=function () {
ctx2.fillStyle=this.colorF;
ctx2.fillText(v,oldX,oldY);
canvas2.TextAutoLine(v,canvas2,oldX,oldY,20);
ctx2.moveTo(oldX, oldY);
canvas2.onmouseup = function () {
ctx2.fillStyle = this.colorF;
ctx2.fillText(v, oldX, oldY);
canvas2.TextAutoLine(v, canvas2, oldX, oldY, 20);
// Txt.value = "";
Txt2.style.display="none";
Txt2.style.display = "none";
}
}
}
},
// 文字
word1(){
word1() {
let canvas3 = document.getElementById('canvas');
let ctx3 = canvas3.getContext('2d');
let Txt3 = document.getElementById('txt');
let word3 = document.getElementById('word');
Txt3.style.display="none";
ctx3.font="16px Microsoft Yahei";
canvas3.onmousedown=function () {
Txt3.style.display = "none";
ctx3.font = "16px Microsoft Yahei";
canvas3.onmousedown = function () {
ctx3.closePath();
}
canvas3.onmouseup=function (ev) {
var inputV= document.getElementById('inputV').value;
if(inputV == 1){
canvas3.onmouseup = function (ev) {
var inputV = document.getElementById('inputV').value;
if (inputV == 1) {
document.getElementById('word').focus();
// console.log(ev.offsetX,ev.offsetY);
var oldX = ev.offsetX;
var oldY = ev.offsetY;
word3.style.display="block";
word3.style.left=oldX+'px';
word3.style.top =oldY+'px';
word3.style.display = "block";
word3.style.left = oldX + 'px';
word3.style.top = oldY + 'px';
word3.onblur=function () {
word3.onblur = function () {
let v = word3.value;
if(v != '' && v != ' '){
this.imgData=ctx3.getImageData(0,0,canvas3.width,canvas3.height);
let img = ctx3.getImageData(0,0,canvas3.width,canvas3.height);
if (v != '' && v != ' ') {
this.imgData = ctx3.getImageData(0, 0, canvas3.width, canvas3.height);
let img = ctx3.getImageData(0, 0, canvas3.width, canvas3.height);
preDrawAry.push(img);
ctx3.moveTo(oldX,oldY);
ctx3.fillStyle="#e42343";
ctx3.moveTo(oldX, oldY);
ctx3.fillStyle = "#e42343";
let lineWidth = 0;
let canvasWidth = canvas3.width;
let lastSubStrIndex= 0;
for(let i=0;i<v.length;i++){
lineWidth+=ctx3.measureText(v[i]).width;
if(lineWidth>canvasWidth-oldX){
ctx3.fillText(v.substring(lastSubStrIndex,i),oldX,(oldY+10));
oldY+=20;
lineWidth=0;
lastSubStrIndex=i;
let lastSubStrIndex = 0;
for (let i = 0; i < v.length; i++) {
lineWidth += ctx3.measureText(v[i]).width;
if (lineWidth > canvasWidth - oldX) {
ctx3.fillText(v.substring(lastSubStrIndex, i), oldX, (oldY + 10));
oldY += 20;
lineWidth = 0;
lastSubStrIndex = i;
}
if(i==v.length-1){
ctx3.fillText(v.substring(lastSubStrIndex,i+1),oldX,(oldY+10));
if (i == v.length - 1) {
ctx3.fillText(v.substring(lastSubStrIndex, i + 1), oldX, (oldY + 10));
}
}
inputV ="2";
inputV = "2";
word3.value = "";
}
}
@ -547,42 +570,42 @@
}
},
// 文字过长超出换行toDataURL()
canvasTextAutoLine(str,canvas,initX,initY,lineHeight){
canvasTextAutoLine(str, canvas, initX, initY, lineHeight) {
let ctx = canvas.getContext("2d");
let lineWidth = 0;
let canvasWidth = canvas.width;
let lastSubStrIndex= 0;
for(let i=0;i<str.length;i++){
lineWidth+=ctx.measureText(str[i]).width;
if(lineWidth>canvasWidth-initX){
ctx.fillText(str.substring(lastSubStrIndex,i),initX,initY);
initY+=lineHeight;
lineWidth=0;
lastSubStrIndex=i;
let lastSubStrIndex = 0;
for (let i = 0; i < str.length; i++) {
lineWidth += ctx.measureText(str[i]).width;
if (lineWidth > canvasWidth - initX) {
ctx.fillText(str.substring(lastSubStrIndex, i), initX, initY);
initY += lineHeight;
lineWidth = 0;
lastSubStrIndex = i;
}
if(i==str.length-1){
ctx.fillText(str.substring(lastSubStrIndex,i+1),initX,initY);
if (i == str.length - 1) {
ctx.fillText(str.substring(lastSubStrIndex, i + 1), initX, initY);
}
}
},
// 撤销
back(){
this.word.style.display="none";
this.Txt.style.display="none";
if(preDrawAry.length>0) {
back() {
this.word.style.display = "none";
this.Txt.style.display = "none";
if (preDrawAry.length > 0) {
var popData = preDrawAry.pop();
this.ctx.putImageData(popData, 0, 0);
}
},
// 回退一次
put(){
this.ctx.putImageData(this.imgData,0,0);
put() {
this.ctx.putImageData(this.imgData, 0, 0);
},
//保存
saveTu(){
saveTu() {
let that = this;
this.word.style.display="none";
this.Txt.style.display="none";
this.word.style.display = "none";
this.Txt.style.display = "none";
let canvas = document.getElementById('canvas');
let image = new Image();
image = canvas.toDataURL('image/png');
@ -591,7 +614,7 @@
let formData = new FormData();
formData.append('file', file);
upFile(formData).then((res) => {
that.imgUrl=res.data.path;
that.imgUrl = res.data.path;
})
},
//base64ToFile
@ -599,69 +622,69 @@
let arr = baseUrl.split(',');
// let type = arr[0].match(/:(.*?);/)[1]; // 解锁图片类型
let bytes = atob(arr[1]); // 解码base64
let n = bytes .length;
let n = bytes.length;
let bufferArray = new Uint8Array(n);
while (n--) {
bufferArray[n] = bytes.charCodeAt(n);
}
// let fileOfBlob = new File([bufferArray], new Date()+'.jpg');
return new File([bufferArray ],'draw.jpg');
return new File([bufferArray], 'draw.jpg');
},
/* 图片保存 */
//最终表格判定
judgeForm(){
let that = this ,
judgeForm() {
let that = this,
reg = /\{(.+?)\}/g,
judgeList = this.judgeList;
for(let i=0;i<judgeList.length;i++){
let arr = [],str = '';
let item = judgeList[i].rule_expression.replace(/`/g,'');
if(item.indexOf('||')>-1){
for (let i = 0; i < judgeList.length; i++) {
let arr = [], str = '';
let item = judgeList[i].rule_expression.replace(/`/g, '');
if (item.indexOf('||') > -1) {
arr = item.split('||');
}else if(item.indexOf('&&')>-1){
} else if (item.indexOf('&&') > -1) {
arr = item.split('&&');
}else{
} else {
arr.push(item);
}
//对每个条件进行判定如果符合
for (let i = 0;i<arr.length;i++){
for (let i = 0; i < arr.length; i++) {
//获取判断依据
let a = '`'+ arr[i]+'`';
let tem =a.match(reg)[0];
let a = '`' + arr[i] + '`';
let tem = a.match(reg)[0];
let ky = tem.replace(/\{|\}/g, '');//qipao
//有值时进行判断
if(that.checkForm[ky]!==''&&that.checkForm[ky]!==null&&that.checkForm[ky]!==undefined){
if (that.checkForm[ky] !== '' && that.checkForm[ky] !== null && that.checkForm[ky] !== undefined) {
//替换变量
a = a.replace(ky, 'yyy');
let yyy = "'"+that.checkForm[ky]+"'";
if(eval(eval( a))){
let yyy = "'" + that.checkForm[ky] + "'";
if (eval(eval(a))) {
str += 'true';
}else{
} else {
str += 'false';
}
}
}
if(item.indexOf('&&')>-1){
if(str.indexOf('false')>-1){
if (item.indexOf('&&') > -1) {
if (str.indexOf('false') > -1) {
that.judgeList[i].is_testok = true;
}else{
} else {
that.judgeList[i].is_testok = false;
}
}else{
if(str.indexOf('true')>-1){
} else {
if (str.indexOf('true') > -1) {
that.judgeList[i].is_testok = false;
}else{
} else {
that.judgeList[i].is_testok = true;
}
}
}
let real = that.judgeList.filter(item=>{
return item.is_testok===false;
let real = that.judgeList.filter(item => {
return item.is_testok === false;
});
if(real.length>0){
if (real.length > 0) {
that.is_testok = false;
// alert("检验不合格!")
}else{
} else {
that.is_testok = true;
// alert("检验合格!")
}
@ -669,12 +692,13 @@
//提交检查项目
submitfield(isSubmit) {
let that = this;
let drawArr = that.formData.filter(item=>{
return item.field_type==='draw';
that.index = isSubmit;
let drawArr = that.formData.filter(item => {
return item.field_type === 'draw';
});
if(drawArr.length>0){
that.word.style.display="none";
that.Txt.style.display="none";
if (drawArr.length > 0) {
that.word.style.display = "none";
that.Txt.style.display = "none";
let canvas = document.getElementById('canvas');
let image = new Image();
image = canvas.toDataURL('image/png');
@ -683,28 +707,28 @@
let formData = new FormData();
formData.append('file', file);
upFile(formData).then((res) => {
if(res){
if (res) {
let key = drawArr[0].field_key;
that.imgUrl=res.data.path;
that.imgUrl = res.data.path;
that.checkForm[key] = res.data.path;
that.fieldData(isSubmit);
that.fieldData();
}
});
}else{
that.fieldData(isSubmit);
} else {
that.fieldData();
}
},
fieldData(isSubmit){
fieldData() {
debugger;
let that = this;
that.field = []; //检查项目
let submit = isSubmit=='1'?false:true;
that.formData.forEach((item) => {
let field_value;
if(item.field_type==='int'){
if (item.field_type === 'int') {
field_value = parseInt(that.checkForm[item.field_key])
}else if(item.field_type==='float'){
} else if (item.field_type === 'float') {
field_value = parseFloat(that.checkForm[item.field_key])
}else{
} else {
field_value = that.checkForm[item.field_key];
}
that.field.push({
@ -717,14 +741,16 @@
that.testrecord.record_data = that.field;//检查项列表
that.testrecord.is_testok = that.is_testok;//检查表检查结果
that.testrecord.id = that.recordId;//记录id
if(submit){//提交
this.$emit('recordSubmit',that.testrecord);
}else {//保存
this.$emit('recordSave',that.testrecord);
that.testrecord.number = that.numbers;//编号
that.testrecord.remark = that.remark;//备注
if (that.index === '2') {//提交
this.$emit('recordSubmit', that.testrecord);
} else {//保存
this.$emit('recordSave', that.testrecord);
}
},
recordCancel(){
this.$emit('recordCancel','')
recordCancel() {
this.$emit('recordCancel', '')
},
}
}
@ -732,7 +758,7 @@
<style scoped>
canvas {
width:500px!important;
width: 500px !important;
/*border: 1px solid #000000;*/
cursor: crosshair;
margin: auto;
@ -756,6 +782,7 @@
margin-right: 10px;
margin-bottom: 10px;
}
.hide {
display: none;
}
@ -794,23 +821,33 @@
#res {
display: inline-block;
}
.helpText{
.helpText {
position: absolute;
top: 40px;
left: 100px;
}
.adoptTip{
.adoptTip {
position: absolute;
top: 38px;
right: 0;
font-size: 12px;
color: #46ce7a;
}
.failTip{
.failTip {
position: absolute;
top: 38px;
right: 0;
font-size: 12px;
color: #ff0000;
}
#canvasImg{
width:500px;
height: 300px;
position: absolute;
left: 50%;
transform: translateX(-50%)
}
</style>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -113,7 +113,7 @@ export const asyncRoutes = [
path: 'material/:id',
name: 'MaterialDO',
component: () => import('@/views/mtm/materialdo.vue'),
meta: { title: '绑定检查表', perms: ['vendor_manage'] },
meta: { title: '绑定检查表' },
hidden: true
}
,
@ -121,8 +121,21 @@ export const asyncRoutes = [
path: 'materialDetail/:id',
name: 'MaterialDetail',
component: () => import('@/views/mtm/materialDetail.vue'),
meta: { title: '物料详情', perms: ['vendor_manage'] },
meta: { title: '物料详情' },
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',
@ -134,7 +147,7 @@ export const asyncRoutes = [
path: 'step/:id',
name: 'Step',
component: () => import('@/views/mtm/step.vue'),
meta: { title: '子工序', perms: ['vendor_manage'] },
meta: { title: '子工序'},
hidden: true
}
,
@ -142,7 +155,7 @@ export const asyncRoutes = [
path: 'stepdo/:id',
name: 'StepDo',
component: () => import('@/views/mtm/stepdo.vue'),
meta: { title: '子工序查看', perms: ['vendor_manage'] },
meta: { title: '子工序查看'},
hidden: true
},
{
@ -151,18 +164,7 @@ export const asyncRoutes = [
component: () => import('@/views/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',
name: 'work',
component: () => import('@/views/pm/work'),
meta: { title: '生产子计划', perms: ['pm_plan'] },
meta: { title: '生产子计划'},
hidden: true
},
{
@ -199,24 +201,24 @@ export const asyncRoutes = [
component: () => import('@/views/pm/management'),
meta: { title: '生产任务管理', icon: 'productionTask', perms: ['pm_testitem'] }
},
{
path: 'plandetails/:id',
name: 'plandetails',
component: () => import('@/views/pm/plandetails'),
meta: { title: '生产任务详情', perms: ['pm_testitem'] },
meta: { title: '生产任务详情'},
hidden: true
}
,
{
path: 'processcard/:id',
name: 'processcard',
component: () => import('@/views/pm/processcard'),
meta: { title: '流程卡', perms: ['vendor_manage'] },
meta: { title: '流程卡' },
hidden: true
}
]
},
{
@ -226,7 +228,7 @@ export const asyncRoutes = [
name: 'wpm',
meta: { title: '生产执行', icon: 'execute', perms: ['wpm_manage'] },
children: [
{
{
path: 'worktask',
name: 'worktask',
component: () => import('@/views/wpm/worktask'),
@ -261,9 +263,8 @@ export const asyncRoutes = [
path: 'firstCheck',
name: 'firstCheck',
component: () => import('@/views/wpm/firstCheck'),
meta: { title: '首件确认', icon: 'finishedCheck', perms: ['wpm_firstCheck'] ,noCache: true}
meta: { title: '首件确认', icon: 'finishedCheck', perms: ['wpm_firstCheck']}
}
]
},
{
@ -317,10 +318,10 @@ export const asyncRoutes = [
path: 'contractdetail/:id',
name: 'contractdetail',
component: () => import('@/views/sam/contractdetail'),
meta: { title: '合同详情', perms: ['sam_contract'] },
meta: { title: '合同详情'},
hidden: true
}
,
{
path: 'order',
@ -328,13 +329,13 @@ export const asyncRoutes = [
component: () => import('@/views/sam/order'),
meta: { title: '订单管理', icon: 'order', perms: ['sam_order'] }
}
,
{
path: 'orderdetail/:id',
name: 'orderdetail',
component: () => import('@/views/sam/orderdetail'),
meta: { title: '订单详情', perms: ['sam_order'] },
meta: { title: '订单详情'},
hidden: true
},
{
@ -348,7 +349,7 @@ export const asyncRoutes = [
path: 'salesdetail/:id',
name: 'salesdetail',
component: () => import('@/views/sam/salesdetail'),
meta: { title: '销售详情', perms: ['sam_sales'] },
meta: { title: '销售详情'},
hidden: true
}
]
@ -384,7 +385,7 @@ export const asyncRoutes = [
path: 'taskdetails/:id',
name: 'taskdetails',
component: () => import('@/views/qm/taskdetails'),
meta: { title: '过程检验详情', perms: ['qm_processtest'] },
meta: { title: '过程检验详情'},
hidden: true
}
,
@ -392,7 +393,7 @@ export const asyncRoutes = [
path: 'wproduct/:id',
name: 'wproduct',
component: () => import('@/views/qm/wproduct'),
meta: { title: '工序玻璃', perms: ['vendor_manage'] },
meta: { title: '工序玻璃' },
hidden: true
}
,
@ -400,7 +401,7 @@ export const asyncRoutes = [
path: 'taskrecordfrom/:id',
name: 'taskrecordfrom',
component: () => import('@/views/qm/taskrecordfrom'),
meta: { title: '检验记录', perms: ['vendor_manage'] },
meta: { title: '检验记录'},
hidden: true
}
,
@ -416,7 +417,7 @@ export const asyncRoutes = [
component: () => import('@/views/qm/unproduct'),
meta: { title: '不合格品', icon: 'unqualified', perms: ['qm_unproduct'] }
}
]
},
{
@ -424,19 +425,19 @@ export const asyncRoutes = [
component: Layout,
redirect: '/personnel/user',
name: 'personnel',
meta: { title: '人员管理', icon: 'user', perms: ['personnel_set'] },
meta: { title: '人员管理', icon: 'user', perms: ['employee_manage'] },
children: [
{
path: 'user',
name: 'user',
component: () => import('@/views/personnel/user'),
meta: { title: '人员列表', icon: 'userList', perms: ['personnel_user'] }
meta: { title: '人员列表', icon: 'userList', perms: ['employee_userList'] }
},
{
path: 'attendance',
name: 'attendance',
component: () => import('@/views/personnel/attendance'),
meta: { title: '考勤列表', icon: 'attendance', perms: ['personnel_attendance'] }
meta: { title: '考勤列表', icon: 'attendance', perms: ['employee_attendance'] }
} ,{
path: 'userupdate/:id',
name: 'userupdate',
@ -444,7 +445,7 @@ export const asyncRoutes = [
meta: { title: '人员信息详情', icon: 'home' },
hidden: true
},
]
},
{
@ -464,7 +465,7 @@ export const asyncRoutes = [
path: 'inventory/:id',
name: 'inventory',
component: () => import('@/views/inm/inventory'),
meta: { title: '仓库物料', perms: ['vendor_manage'] },
meta: { title: '仓库物料' },
hidden: true
}
,
@ -484,7 +485,7 @@ export const asyncRoutes = [
path: 'fifodetail/:id',
name: 'fifodetail',
component: () => import('@/views/inm/fifodetail'),
meta: { title: '仓库物料', perms: ['vendor_manage'] },
meta: { title: '仓库物料'},
hidden: true
},
{
@ -499,7 +500,7 @@ export const asyncRoutes = [
component: () => import('@/views/inm/product'),
meta: { title: '成品库', icon: 'finishedProduct', perms: ['inm_product'] }
},
]
},
{
@ -507,25 +508,25 @@ export const asyncRoutes = [
component: Layout,
redirect: '/procurement/vendor',
name: 'procurement',
meta: { title: '采购管理', icon: 'purchase', perms: ['procurement_manage'] },
meta: { title: '采购管理', icon: 'purchase', perms: ['pum_manage'] },
children: [
{
path: 'vendor',
name: 'vendor',
component: () => import('@/views/procurement/vendor'),
meta: { title: '供应商', icon: 'supplier', perms: ['procurement_vendor'] }
meta: { title: '供应商', icon: 'supplier', perms: ['pum_vendor'] }
},
{
path: 'puorder',
name: 'puorder',
component: () => import('@/views/procurement/puorder'),
meta: { title: '采购订单', icon: 'purchaseOrder', perms: ['procurement_puorder'] }
meta: { title: '采购订单', icon: 'purchaseOrder', perms: ['pum_puorder'] }
},
{
path: 'puorderitem/:id',
name: 'puorderitem',
component: () => import('@/views/procurement/puorderitem'),
meta: { title: '采购订单项', perms: ['procurement_puorder'] },
meta: { title: '采购订单项'},
hidden: true
}
]
@ -555,18 +556,18 @@ export const asyncRoutes = [
component: () => import('@/views/statistics/personStatistics'),
meta: { title: '人员统计', icon: 'personStatistics', perms: ['statistics_personStatistics'] }
},
{
path: 'costStatistics',
name: 'costStatistics',
component: () => import('@/views/statistics/costStatistics'),
meta: { title: '成本统计', icon: 'costStatistics', perms: ['workflow_index'] }
},
{
path: 'testStatistics',
name: 'testStatistics',
component: () => import('@/views/statistics/testStatistics'),
meta: { title: '检验统计', icon: 'testStatistics', perms: ['workflow_index'] }
},
/* {
path: 'costStatistics',
name: 'costStatistics',
component: () => import('@/views/statistics/costStatistics'),
meta: { title: '成本统计', icon: 'costStatistics', perms: ['workflow_index'] }
},
{
path: 'testStatistics',
name: 'testStatistics',
component: () => import('@/views/statistics/testStatistics'),
meta: { title: '检验统计', icon: 'testStatistics', perms: ['workflow_index'] }
},*/
]
},
@ -648,7 +649,7 @@ export const asyncRoutes = [
meta: { title: '用户管理', icon: 'home', perms: ['user_manage'] }
}
,
{
path: 'organization',
name: 'Organization',
@ -677,7 +678,7 @@ export const asyncRoutes = [
path: 'file',
name: 'File',
component: () => import('@/views/system/file'),
meta: { title: '文件库', icon: 'home', perms: ['file_room'] }
meta: { title: '文件库', icon: 'home', perms: ['system_file'] }
},
{
path: 'task',

View File

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

View File

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

View File

@ -1,6 +1,6 @@
import Cookies from 'js-cookie'
const TokenKey = 'token'
const TokenKey = 'token';
export function getToken() {
return Cookies.get(TokenKey)
@ -14,12 +14,3 @@ export function removeToken() {
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 { MessageBox, Message } from 'element-ui'
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
const service = axios.create({
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
*/
response => {
const res = response.data
const res = response.data;
if(res.code>=200 && res.code<400){
return res
}
@ -68,24 +71,60 @@ service.interceptors.response.use(
duration: 3 * 1000
})
}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: '重新登陆',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
store.dispatch('user/resetToken').then(() => {
store.dispatch('user/logout').then(() => {
location.reload()
})
})
})*/
}
} else if (res.code >= 400) {
Message({
message: res.msg || '请求出错',
type: 'error',
duration: 3 * 1000
})
return Promise.reject(new Error(res.msg || '请求出错'))
if(res.msg.indexOf('请调整位置')>-1){
return;
}else{
Message({
message: res.msg || '请求出错',
type: 'error',
duration: 3 * 1000
})
return Promise.reject(new Error(res.msg || '请求出错'))
}
}
},
error => {

View File

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

View File

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

View File

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

View File

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

View File

@ -47,21 +47,21 @@
v-el-height-adaptive-table="{bottomOffset: 42}"
>
<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 label="设备编号" prop="number" width="120">
<el-table-column label="设备编号" prop="number" min-width="120">
</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 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 label="生产日期" prop="production_date" width="120">
<el-table-column label="生产日期" prop="production_date" min-width="120">
</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 label="数量" prop="count" width="120">
<el-table-column label="数量" prop="count" min-width="120">
</el-table-column>
<el-table-column label="状态" width="120">
<el-table-column label="状态" min-width="120">
<template slot-scope="scope">
<el-tag v-if="scope.row.state===10" type="success">
{{ state_[scope.row.state] }}
@ -77,16 +77,16 @@
</el-tag>
</template>
</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>
</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>
</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>
</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_">
<el-tag v-for="item in scope.row.step_"
:key="item.number"
@ -101,7 +101,7 @@
<el-table-column
align="center"
label="操作"
width="120px"
min-width="120px"
fixed="right"
>
<template slot-scope="scope">

View File

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

View File

@ -62,8 +62,8 @@
height="100"
v-el-height-adaptive-table="{ bottomOffset: 42 }"
>
<el-table-column type="index" width="50" />
<el-table-column label="记录编号" prop="number"> </el-table-column>
<el-table-column type="index" width="50"/>
<el-table-column label="记录编号" prop="number"></el-table-column>
<el-table-column label="操作人员">
<template slot-scope="scope" v-if="scope.row.create_by">
{{ scope.row.create_by_.name }}
@ -80,7 +80,7 @@
<el-tag v-else>已审核</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="create_time"> </el-table-column>
<el-table-column label="创建时间" prop="create_time"></el-table-column>
<el-table-column align="center" label="操作" width="220px">
<template slot-scope="scope">
<el-link
@ -99,7 +99,7 @@
</el-link>
<el-link
v-if="
checkPermission(['fifo_hear']) && scope.row.is_audited == false
checkPermission(['fifo_audit']) && scope.row.is_audited == false
"
type="primary"
@click="handleAudit(scope)"
@ -191,7 +191,7 @@
<span style="float: left">{{ item.batch }}</span>
<span
style="float: right; color: #8492a6; font-size: 13px"
>{{ item.material_.name }}</span
>{{ item.material_.name }}</span
>
</el-option>
</el-select>
@ -346,10 +346,12 @@
label="批次"
: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-col>
<el-col :span="5" style="margin-right: 10px">
</el-row>
<el-row>
<el-col :span="5">
<el-form-item
class="expiration_date"
label="有效期"
@ -365,6 +367,21 @@
</el-date-picker>
</el-form-item>
</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-tooltip
@ -422,298 +439,345 @@
</div>
</template>
<script>
import {
getfifoList,
createInventory,
createInother,
getWarehouseList,
deleteFifoitem,
getmaterialbatchList,
deleteFifo,
audit,
outOther,
} from "@/api/inm";
import { getPuorderList } from "@/api/pum";
import checkPermission from "@/utils/permission";
import { getpVendorList } from "@/api/vendor";
import { getMaterialList } from "@/api/mtm";
import { getUserList } from "@/api/user";
import { genTree } from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaulteinventory = {
vendor: null,
details: [
{
warehouse: "", //仓库
material: "", // 物料
count: "", //数量
batch: "", //批次
},
],
};
const defaulteoutfifo = {
details: [
{
material_batch: null,
count: null,
},
],
};
export default {
components: { Pagination },
data() {
return {
inventory: defaulteinventory,
outfifo: defaulteoutfifo,
dialogVisibleout: false,
fifoList: {
count: 0,
import {
getfifoList,
createInventory,
createInother,
getWarehouseList,
deleteFifoitem,
getmaterialbatchList,
deleteFifo,
audit,
outOther,
} from "@/api/inm";
import {getPuorderList} from "@/api/pum";
import checkPermission from "@/utils/permission";
import {getpVendorList} from "@/api/vendor";
import {getMaterialList} from "@/api/mtm";
import {getUserList} from "@/api/user";
import {genTree} from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaulteinventory = {
vendor: null,
details: [
{
warehouse: "", //仓库
material: "", // 物料
count: "", //数量
batch: "", //批次
expiration_date: null, //
details:[],
},
types_: {
1: "生产领料",
2: "销售提货",
3: "采购入库",
4: "生产入库",
5: "其他入库",
6:"其他出库",
],
};
const defaulteoutfifo = {
details: [
{
material_batch: null,
count: null,
},
inpur: {},
listQuery: {
page: 1,
page_size: 20,
},
puorderoptions: [],
materialbatchoptions: [],
warehouseData: [],
materialoptions: [],
vendoroptions: [],
listLoading: true,
dialogVisible: false,
dialogType: "new",
dialogVisibles: false,
rule1: {
name: [{ required: true, message: "请输入", trigger: "blur" }],
},
};
},
computed: {},
watch: {},
created() {
this.getlists();
this.getList();
this.getListgys();
this.getmaterialList();
this.getpuorderList();
},
methods: {
checkPermission,
getList() {
this.listLoading = true;
getfifoList(this.listQuery).then((response) => {
if (response.data) {
this.fifoList = response.data;
],
};
export default {
components: {Pagination},
data() {
const validateBatch = (rule, value, callback) => {
if (value.length < 6) {
callback(new Error("请输入不小于六位!"));
} else {
callback();
}
this.listLoading = false;
});
},
//出入库详情
handleDetail(scope) {
this.$router.push({
name: "fifodetail",
params: { id: scope.row.id, pu_order: scope.row.pu_order },
});
},
//供应商列表
getListgys() {
getpVendorList({ page: 0 }).then((response) => {
if (response.data) {
this.vendoroptions = response.data;
}
});
},
//采购订单
getpuorderList() {
getPuorderList({ page: 0 }).then((response) => {
if (response.data) {
this.puorderoptions = response.data;
}
});
},
//采购入库提交
confirminpur() {
createInventory(this.inpur).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisibles = false;
this.$message.success("成功");
}
});
},
//仓库
getlists() {
getWarehouseList({ page: 0 }).then((response) => {
if (response.data) {
this.warehouseData = genTree(response.data);
}
this.listLoading = false;
});
},
handlecgCreate() {
this.dialogVisibles = true;
},
addConditions1() {
if (this.outfifo.details.length <= 10) {
this.outfifo.details.push({
material_batch: null,
count: null,
});
} else {
this.$message("最多可添加十项条件");
}
},
addConditions() {
if (this.inventory.details.length <= 10) {
this.inventory.details.push({
warehouse: "", //仓库
material: "", // 物料
count: "", //数量
batch: "", // 批次
});
} else {
this.$message("最多可添加十项条件");
}
},
deleteItem(index) {
this.inventory.details.splice(index, 1);
},
deleteItem1(index) {
this.outfifo.details.splice(index, 1);
},
//物料
getmaterialList() {
this.listLoading = true;
getMaterialList({ pageoff: true }).then((response) => {
if (response.data) {
this.materialoptions = genTree(response.data);
}
this.listLoading = false;
});
},
//其他入库
handleCreate() {
this.inventory.details = [
{
warehouse: "", // 仓库
material: "", // 物料
count: "", //数量
batch: "", //批次
},
];
this.inventory = Object.assign({}, defaulteinventory);
this.dialogType = "new";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
//其他出库
handleoutCreate() {
this.outfifo.details = [
{
material_batch: null,
count: null,
},
];
this.outfifo = Object.assign({}, defaulteoutfifo);
this.dialogVisibleout = true;
getmaterialbatchList({ page: 0 }).then((response) => {
if (response.data) {
this.materialbatchoptions = response.data;
}
});
this.$nextTick(() => {
this.$refs["Formout"].clearValidate();
});
},
confirmoutfifo() {
console.log(this.outfifo);
outOther(this.outfifo).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisibleout = false;
this.$message.success("成功");
}
});
},
//审核
handleAudit(scope) {
this.$confirm("是否通过?", "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "success",
})
.then(async () => {
await audit(scope.row.id);
this.getList();
this.$message.success("已审核");
})
.catch((err) => {
console.error(err);
});
},
handleFilter() {
this.listQuery.page = 1;
this.getList();
},
resetFilter() {
this.listQuery = {
page: 1,
page_size: 20,
};
return {
inventory: defaulteinventory,
outfifo: defaulteoutfifo,
dialogVisibleout: false,
fifoList: {
count: 0,
},
itemDetails:'',
types_: {
1: "生产领料",
2: "销售提货",
3: "采购入库",
4: "生产入库",
5: "其他入库",
6: "其他出库",
},
inpur: {},
listQuery: {
page: 1,
page_size: 20,
},
puorderoptions: [],
materialbatchoptions: [],
warehouseData: [],
materialoptions: [],
vendoroptions: [],
listLoading: true,
dialogVisible: false,
dialogType: "new",
dialogVisibles: false,
rule1: {
name: [{required: true, message: "请输入", trigger: "blur"}],
batch: [{required: true, message: "请输入不小于六位", trigger: "blur", validator: validateBatch},],
},
};
},
computed: {},
watch: {},
created() {
this.getlists();
this.getList();
this.getListgys();
this.getmaterialList();
this.getpuorderList();
},
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,
getList() {
this.listLoading = true;
async confirm(form) {
console.log(this.inventory);
createInother(this.inventory).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deleteFifo(scope.row.id);
this.getList();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
getfifoList(this.listQuery).then((response) => {
if (response.data) {
this.fifoList = response.data;
}
this.listLoading = false;
});
},
//出入库详情
handleDetail(scope) {
this.$router.push({
name: "fifodetail",
params: {id: scope.row.id, pu_order: scope.row.pu_order},
});
},
//供应商列表
getListgys() {
getpVendorList({page: 0}).then((response) => {
if (response.data) {
this.vendoroptions = response.data;
}
});
},
//采购订单
getpuorderList() {
getPuorderList({page: 0}).then((response) => {
if (response.data) {
this.puorderoptions = response.data;
}
});
},
//采购入库提交
confirminpur() {
createInventory(this.inpur).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisibles = false;
this.$message.success("成功");
}
});
},
//仓库
getlists() {
getWarehouseList({page: 0}).then((response) => {
if (response.data) {
this.warehouseData = genTree(response.data);
}
this.listLoading = false;
});
},
handlecgCreate() {
this.dialogVisibles = true;
},
addConditions1() {
if (this.outfifo.details.length <= 10) {
this.outfifo.details.push({
material_batch: null,
count: null,
});
} else {
this.$message("最多可添加十项条件");
}
},
addConditions() {
if (this.inventory.details.length <= 10) {
this.inventory.details.push({
warehouse: "", //仓库
material: "", // 物料
count: "", //数量
batch: "", // 批次
details:[]
});
} else {
this.$message("最多可添加十项条件");
}
},
deleteItem(index) {
this.inventory.details.splice(index, 1);
},
deleteItem1(index) {
this.outfifo.details.splice(index, 1);
},
//物料
getmaterialList() {
this.listLoading = true;
getMaterialList({pageoff: true}).then((response) => {
if (response.data) {
this.materialoptions = genTree(response.data);
}
this.listLoading = false;
});
},
//其他入库
handleCreate() {
this.inventory.details = [
{
warehouse: "", // 仓库
material: "", // 物料
count: "", //数量
batch: "", //批次
expiration_date: null, //
details:[],
},
];
this.inventory = Object.assign({}, defaulteinventory);
this.dialogType = "new";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
//其他出库
handleoutCreate() {
this.outfifo.details = [
{
material_batch: null,
count: null,
},
];
this.outfifo = Object.assign({}, defaulteoutfifo);
this.dialogVisibleout = true;
getmaterialbatchList({page: 0}).then((response) => {
if (response.data) {
this.materialbatchoptions = response.data;
}
});
this.$nextTick(() => {
this.$refs["Formout"].clearValidate();
});
},
confirmoutfifo() {
console.log(this.outfifo);
outOther(this.outfifo).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisibleout = false;
this.$message.success("成功");
}
});
},
//审核
handleAudit(scope) {
this.$confirm("是否通过?", "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "success",
})
.then(async () => {
await audit(scope.row.id);
this.getList();
this.$message.success("已审核");
})
.catch((err) => {
console.error(err);
});
},
handleFilter() {
this.listQuery.page = 1;
this.getList();
},
resetFilter() {
this.listQuery = {
page: 1,
page_size: 20,
};
this.getList();
},
async confirm(form) {
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) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
}
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deleteFifo(scope.row.id);
this.getList();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
});
},
//装箱
handlePack(scope) {
this.$router.push({
name: "salesdetail",
params: {id: scope.row.sale},
});
},
},
//装箱
handlePack(scope) {
this.$router.push({
name: "salesdetail",
params: { id: scope.row.sale },
});
},
},
};
};
</script>

View File

@ -53,8 +53,9 @@
v-if="this.$route.params.pu_order != null"
>
<template slot-scope="scope">
<el-tag v-if="scope.row.is_testok == false">不合格</el-tag>
<el-tag v-else>合格</el-tag>
<el-tag v-if="scope.row.is_testok">合格</el-tag>
<el-tag v-else-if="scope.row.is_testok===null">未复验</el-tag>
<el-tag v-else>不合格</el-tag>
</template>
</el-table-column>
@ -86,7 +87,7 @@
复验记录
</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"
@click="handleMaterial(scope)"
>
@ -462,7 +463,7 @@
<el-col v-for="item in recordFieldList" :key="item.id" :span="24">
<div class="items" v-if="item.field_type==='draw'" style="height: 400px">
<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>
</el-col>
</el-row>

View File

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

View File

@ -44,9 +44,8 @@
fit
stripe
highlight-current-row
max-height="620"
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 label="物料编号">
@ -85,13 +84,12 @@
>检查表
</el-link>
<el-link
subproduction_delete
v-if="checkPermission(['material_update'])"
type="primary"
@click="handleEdit(scope)"
>编辑
</el-link>
<el-link
v-if="checkPermission(['material_update'])"
type="primary"
@click="handledetail(scope)"
>详情
@ -134,7 +132,6 @@
<el-form-item label="规格型号">
<el-input v-model="material.specification" placeholder="规格型号"/>
</el-form-item>
<el-form-item label="计量单位">
<el-select style="width: 100%" v-model="material.unit" placeholder="请选择">
<el-option
@ -146,7 +143,6 @@
</el-option>
</el-select>
</el-form-item>
<el-form-item label="物料类别">
<el-select style="width: 100%" v-model="material.type" placeholder="请选择物料类别">
<el-option
@ -167,6 +163,21 @@
<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-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>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
@ -185,9 +196,8 @@
getProcessList
} from "@/api/mtm";
import checkPermission from "@/utils/permission";
import {genTree} from "@/utils";
import {upUrl, upHeaders} from "@/api/file";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaultmaterial = {
name: null,
@ -199,6 +209,7 @@
sort_str: null,
count_safe: 0,
processes: [],
file:null,
};
export default {
components: {Pagination},
@ -208,6 +219,9 @@
materialList: {
count: 0,
},
upHeaders: upHeaders(),
upUrl: upUrl(),
fileList: [],
processOptions: [],
options_: {
// "1": '成品',
@ -246,8 +260,7 @@
}, {
value: '',
label: ''
},
{
}, {
value: '',
label: ''
}, {
@ -256,6 +269,27 @@
}, {
value: '',
label: ''
}, {
value: 'g',
label: 'g'
}, {
value: 'kg',
label: 'kg'
}, {
value: '',
label: ''
}, {
value: '',
label: ''
}, {
value: '',
label: ''
}, {
value: '',
label: ''
}, {
value: '',
label: ''
},
],
listQuery: {
@ -282,6 +316,19 @@
},
methods: {
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){
this.$router.push({name: "MaterialDetail", params: { id: scope.row.id,type: scope.row.type }, })
@ -312,9 +359,23 @@
this.processOptions = res.data.results;
});
},
//绑定工序
//检查表
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() {
this.listQuery.page = 1;
@ -332,14 +393,31 @@
this.material = Object.assign({}, defaultmaterial);
this.dialogType = "new";
this.dialogVisible = true;
if (this.material.file) {
this.fileList = [
{
name: this.process.instruction_.name,
url: this.process.instruction_.path,
},
];
}
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleEdit(scope) {
this.fileList = [];
this.material = Object.assign({}, scope.row); // copy obj
this.dialogType = "edit";
this.dialogVisible = true;
if (this.material.file) {
this.fileList = [
{
name: this.material.file_.name,
url: this.material.file_.path,
},
];
}
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
@ -368,6 +446,7 @@
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.fileList = [];
this.$message.success("成功");
}
});
@ -376,6 +455,7 @@
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.fileList = [];
this.$message.success("成功");
}
});

View File

@ -9,28 +9,31 @@
border
>
<el-descriptions-item label="物料编号">
{{ materialdetail.number }}</el-descriptions-item
>
{{ materialdetail.number }}
</el-descriptions-item>
<el-descriptions-item label="物料名称">
{{ materialdetail.name }}</el-descriptions-item
>
{{ materialdetail.name }}
</el-descriptions-item>
<el-descriptions-item label="规格型号" :span="2">
{{ materialdetail.specification }}</el-descriptions-item
>
{{ materialdetail.specification }}
</el-descriptions-item>
<el-descriptions-item label="计量单位">
{{ materialdetail.unit }}
</el-descriptions-item>
<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-card>
<el-tabs v-model="activeName" type="card">
<el-tab-pane
v-if="this.type == 3 || this.type == 4"
label="供应商"
name="5"
v-if="this.type == 3 || this.type == 4"
>
</el-tab-pane>
<el-tab-pane label="批次" name="3">
@ -42,42 +45,30 @@
height="460"
highlight-current-row
>
<el-table-column type="index" width="50" />
<el-table-column type="index" width="50"/>
<el-table-column label="物料批次">
<template slot-scope="scope">{{ scope.row.batch }}</template>
</el-table-column>
<el-table-column label="物料名称">
<template slot-scope="scope">{{
scope.row.material_.name
}}</template>
<template slot-scope="scope">{{scope.row.material_.name}}</template>
</el-table-column>
<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 label="物料编号">
<template slot-scope="scope">{{
scope.row.material_.number
}}</template>
<template slot-scope="scope">{{scope.row.material_.number}}</template>
</el-table-column>
<el-table-column label="仓库名称">
<template slot-scope="scope">{{
scope.row.warehouse_.name
}}</template>
<template slot-scope="scope">{{scope.row.warehouse_.name}}</template>
</el-table-column>
<el-table-column label="仓库编号">
<template slot-scope="scope">{{
scope.row.warehouse_.number
}}</template>
<template slot-scope="scope">{{scope.row.warehouse_.number}}</template>
</el-table-column>
<el-table-column label="物料总存量">
<template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="关联的订单" name="1">
<el-table
:data="orderlist"
@ -87,7 +78,7 @@
highlight-current-row
height="460"
>
<el-table-column type="index" width="50" />
<el-table-column type="index" width="50"/>
<el-table-column label="订单编号" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.number }}</template>
@ -95,22 +86,26 @@
<el-table-column label="客户" show-overflow-tooltip>
<template slot-scope="scope">{{
scope.row.customer_.name
}}</template>
}}
</template>
</el-table-column>
<el-table-column label="所属合同" show-overflow-tooltip>
<template slot-scope="scope">{{
scope.row.contract_.name
}}</template>
}}
</template>
</el-table-column>
<el-table-column label="产品名称" show-overflow-tooltip>
<template slot-scope="scope">{{
scope.row.product_.name
}}</template>
}}
</template>
</el-table-column>
<el-table-column label="产品型号" show-overflow-tooltip>
<template slot-scope="scope">{{
scope.row.product_.specification
}}</template>
}}
</template>
</el-table-column>
<el-table-column label="产品数量">
<template slot-scope="scope">{{ scope.row.count }}</template>
@ -118,12 +113,14 @@
<el-table-column label="交货日期">
<template slot-scope="scope">{{
scope.row.delivery_date
}}</template>
}}
</template>
</el-table-column>
<el-table-column label="创建时间">
<template slot-scope="scope">{{
scope.row.create_time
}}</template>
}}
</template>
</el-table-column>
</el-table>
</el-tab-pane>
@ -136,7 +133,7 @@
style="width: 100%"
height="460"
>
<el-table-column type="index" width="50" />
<el-table-column type="index" width="50"/>
<el-table-column label="任务编号">
<template slot-scope="scope">{{ scope.row.number }}</template>
@ -144,12 +141,14 @@
<el-table-column label="订单编号">
<template slot-scope="scope">{{
scope.row.order_.number
}}</template>
}}
</template>
</el-table-column>
<el-table-column label="合同编号">
<template slot-scope="scope">{{
scope.row.order_.contract_.number
}}</template>
}}
</template>
</el-table-column>
<el-table-column label="生产数量">
@ -164,7 +163,8 @@
<el-table-column label="交付截止时间">
<template slot-scope="scope">{{
scope.row.order_.delivery_date
}}</template>
}}
</template>
</el-table-column>
<el-table-column label="是否生成子计划">
@ -176,7 +176,8 @@
<el-table-column label="创建时间">
<template slot-scope="scope">{{
scope.row.create_time
}}</template>
}}
</template>
</el-table-column>
</el-table>
</el-tab-pane>
@ -193,7 +194,7 @@
style="width: 100%"
height="460"
>
<el-table-column type="index" width="50" />
<el-table-column type="index" width="50"/>
<el-table-column label="玻璃编号">
<template slot-scope="scope">{{ scope.row.number }}</template>
@ -205,18 +206,24 @@
<el-table-column label="状态">
<template slot-scope="scope">{{
actstate_[scope.row.act_state]
}}</template>
}}
</template>
</el-table-column>
<el-table-column label="仓库">
<template slot-scope="scope" v-if="scope.row.warehouse_">{{
scope.row.warehouse_.name
}}</template>
}}
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<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-table
@ -227,43 +234,38 @@
style="width: 100%"
height="460"
>
<el-table-column type="index" width="50" />
<el-table-column type="index" width="50"/>
<el-table-column label="名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column label="单位">
<template slot-scope="scope">{{ scope.row.unit }}</template>
</el-table-column>
<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
align="center"
label="操作"
width="220px"
>
<template slot-scope="scope">
<el-link
v-if="checkPermission(['packitem_update'])"
type="primary"
@click="handleEdit(scope)"
>
编辑
</el-link>
<el-link
v-if="checkPermission(['packitem_delete'])"
type="danger"
@click="handleDelete(scope)"
>
删除
</el-link>
</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
width="220px"
>
<template slot-scope="scope">
<el-link
type="primary"
@click="handleEdit(scope)"
>编辑
</el-link>
<el-link
type="danger"
@click="handleDelete(scope)"
>删除
</el-link>
</template>
</el-table-column>
</el-table>
<el-dialog
:visible.sync="dialogVisible"
@ -275,29 +277,30 @@
:model="packitem"
label-width="100px"
label-position="right"
:rules="rule1"
:rules="rule1"
>
<el-form-item label="物料"
prop="material"
<el-form-item label="物料"
prop="material"
>
<el-select v-model="packitem.material" @change="selectmaterial" >
<el-select v-model="packitem.material" @change="selectmaterial">
<el-option
v-for="item in materialoptions"
:key="item.id"
:value="item.id"
: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-select>
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input v-model="packitem.name" placeholder="名称" />
<el-input v-model="packitem.name" placeholder="名称"/>
</el-form-item>
<el-form-item label="单位" prop="unit">
<el-input v-model="packitem.unit" placeholder="单位" />
<el-input v-model="packitem.unit" placeholder="单位"/>
</el-form-item>
<el-form-item label="型号" prop="specification">
<el-input v-model="packitem.specification" placeholder="型号" />
<el-form-item label="型号" prop="specification">
<el-input v-model="packitem.specification" placeholder="型号"/>
</el-form-item>
<el-form-item label="数量" prop="count">
<el-input-number
@ -318,9 +321,12 @@
</el-form-item>
</el-form>
<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>
</div>
</el-dialog>
@ -331,100 +337,102 @@
</template>
<script>
import checkPermission from "@/utils/permission";
import vueJsonEditor from "vue-json-editor";
import { upUrl, upHeaders } from "@/api/file";
import { getProductionplanList } from "@/api/pm";
import { getmaterialbatchList } from "@/api/inm";
import { getOrderList } from "@/api/sam";
import { getMaterial,getpackitemList,createpackitem,updatepackitem,deletepackitem,getMaterialList } from "@/api/mtm";
import { getwproductList } from "@/api/wpm";
import checkPermission from "@/utils/permission";
import vueJsonEditor from "vue-json-editor";
import {upUrl, upHeaders} from "@/api/file";
import {getProductionplanList} from "@/api/pm";
import {getmaterialbatchList} from "@/api/inm";
import {getOrderList} from "@/api/sam";
import {
getMaterial,
getpackitemList,
createpackitem,
updatepackitem,
deletepackitem,
getMaterialList
} from "@/api/mtm";
import {getwproductList} from "@/api/wpm";
import { upFile } from "@/api/file";
import { genTree } from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
const defaultpackitem = {
name:"",
unit:"",
specification:"",
import {upFile} from "@/api/file";
import {genTree} from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
const defaultpackitem = {
name: "",
unit: "",
specification: "",
};
export default {
components: { Pagination, vueJsonEditor, Treeselect },
data() {
return {
materialdetail: "",
orderlist: [],
wproductList: [],
productionplanList: [],
InventoryList: [],
activeName: "3",
packitem:defaultpackitem,
dialogVisible: false,
dialogType: "new",
pickList:[],
materialoptions:[],
actstate_: {
6: "待复检",
10: "操作进行中",
20: "待检验",
30: "已合格",
40: "库存中",
50: "不合格",
60: "待成品检验",
8: "操作准备中",
26: "待夹层检验",
70: "报废",
},
rule1: {
export default {
components: {Pagination, vueJsonEditor, Treeselect},
data() {
return {
materialdetail: "",
orderlist: [],
wproductList: [],
productionplanList: [],
InventoryList: [],
activeName: "3",
packitem: defaultpackitem,
dialogVisible: false,
dialogType: "new",
pickList: [],
materialoptions: [],
actstate_: {
6: "待复检",
10: "操作进行中",
20: "待检验",
30: "已合格",
40: "库存中",
50: "不合格",
60: "待成品检验",
8: "操作准备中",
26: "待夹层检验",
70: "报废",
},
rule1: {
name: [{required: true, message: "请输入名称", trigger: "blur"}],
unit: [{required: true, message: "请输入单位", trigger: "blur"}],
},
};
},
computed: {},
watch: {},
created() {
this.material = this.$route.params.id;
this.type = this.$route.params.type;
this.getMaterialist()
this.getMaterial();
this.getpickList();
this.getOrderList();
this.getplanList();
this.getmaterialbatchList();
this.getwproductList();
},
methods: {
//新增装箱单
getMaterialist()
{
getMaterialList({ pageoff: true,type:3 }).then((response) => {
if (response.data) {
this.materialoptions = response.data;
}
});
};
},
computed: {},
watch: {},
created() {
this.material = this.$route.params.id;
this.type = this.$route.params.type;
this.getMaterialist();
this.getMaterial();
this.getpickList();
this.getOrderList();
this.getplanList();
this.getmaterialbatchList();
this.getwproductList();
},
methods: {
checkPermission,
//新增装箱单
getMaterialist() {
getMaterialList({pageoff: true, type: 3}).then((response) => {
if (response.data) {
this.materialoptions = response.data;
}
});
},
selectmaterial(selval){
getMaterial(selval).then((response) => {
if (response.data) {
this.packitem.name = response.data.name;
selectmaterial(selval) {
getMaterial(selval).then((response) => {
if (response.data) {
this.packitem.name = response.data.name;
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.dialogType = "new";
this.dialogVisible = true;
@ -440,6 +448,7 @@ handleCreate() {
this.$refs["Form"].clearValidate();
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
@ -455,6 +464,7 @@ handleCreate() {
console.error(err);
});
},
async confirm(form) {
this.$refs[form].validate((valid) => {
if (valid) {
@ -468,7 +478,7 @@ handleCreate() {
}
});
} else {
this.packitem.product=this.material;
this.packitem.product = this.material;
createpackitem(this.packitem).then((res) => {
if (res.code >= 200) {
this.getpickList();
@ -483,56 +493,57 @@ handleCreate() {
});
},
getpickList()
{
getpackitemList({ product: this.material, page: 0 }).then((response) => {
if (response.data) {
this.pickList = response.data; //zhuangxiang信息
}
});
},
getMaterial() {
getMaterial(this.material).then((response) => {
if (response.data) {
this.materialdetail = response.data; //物料基本信息
}
});
},
getOrderList() {
getOrderList({ material: this.material, page: 0 }).then((response) => {
if (response.data) {
this.orderlist = response.data; //物料关联的订单
}
});
},
getplanList() {
getProductionplanList({ material: this.material, page: 0 }).then(
(response) => {
getpickList() {
getpackitemList({product: this.material, page: 0}).then((response) => {
if (response.data) {
this.productionplanList = response.data; //物料关联计划
this.pickList = response.data; //zhuangxiang信息
}
}
);
},
});
},
getmaterialbatchList() {
getmaterialbatchList({ material: this.material, page: 0 }).then(
(response) => {
getMaterial() {
getMaterial(this.material).then((response) => {
if (response.data) {
this.InventoryList = response.data;
// debugger;
this.materialdetail = response.data; //物料基本信息
}
}
);
});
},
getOrderList() {
getOrderList({material: this.material, page: 0}).then((response) => {
if (response.data) {
this.orderlist = response.data; //物料关联的订单
}
});
},
getplanList() {
getProductionplanList({material: this.material, page: 0}).then(
(response) => {
if (response.data) {
this.productionplanList = response.data; //物料关联计划
}
}
);
},
getmaterialbatchList() {
getmaterialbatchList({material: this.material, page: 0}).then(
(response) => {
if (response.data) {
this.InventoryList = response.data;
}
}
);
},
getwproductList() {
getwproductList({material: this.material, page: 0}).then((response) => {
if (response.data) {
this.wproductList = response.data; //半成品
}
});
},
},
getwproductList() {
getwproductList({ material: this.material, page: 0 }).then((response) => {
if (response.data) {
this.wproductList = response.data; //半成品
}
});
},
},
};
};
</script>

View File

@ -1,6 +1,14 @@
<template>
<div class="app-container">
<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-col :span="10">
@ -113,6 +121,20 @@
</el-option>
</el-select>
</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-switch v-model="recordform.enabled"></el-switch>
</el-form-item>
@ -132,7 +154,8 @@
:title="tableForm.name"
>
<customForm
:results="fieldList.results"
v-if="dialogVisibleForm"
:results="dialogFieldList"
:hasPicture="hasPicture"
:formID="formID"
:isDisabled="isDisabled"
@ -435,9 +458,9 @@
</el-col>
</el-row>
</el-form-item>
<el-form-item label="字段父级">
<!--<el-form-item label="字段父级">
<treeselect v-model="field.parent" :multiple="false" :options="treeDate" placeholder="字段父级"/>
</el-form-item>
</el-form-item>-->
<el-form-item label="字段说明">
<el-input v-model="field.help_text" placeholder="字段名称"/>
</el-form-item>
@ -519,23 +542,21 @@
import {upFile} from "@/api/file";
import {genTree} from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import Treeselect from '@riophae/vue-treeselect';
import '@riophae/vue-treeselect/dist/vue-treeselect.css';
const defaultstep = {
name: "",
number: "",
};
const defaultrecordform = {enabled: false};
const defaultfield = {};
let preDrawAry = [];
export default {
components: {Pagination, vueJsonEditor, Treeselect, customForm, faceLogin},
components: {Pagination,customForm, faceLogin},
data() {
return {
item:{},
step: defaultstep,
stepList: [],
dialogFieldList: [],
upHeaders: upHeaders(),
upUrl: upUrl(),
fileList: [],
@ -575,7 +596,7 @@
},
listQueryrecordform: {
page: 1,
page_size: 20,
page_size: 99,
},
recordformList: {
count: 0,
@ -673,10 +694,19 @@
],
typeOptions_:{
10 : "生产记录表",
20 : "工序检查表",
30 : "入厂检验表",
40 : "成品检验表",
50 : "首件检查表",
20 : "工序检查表",//wp p
30 : "入厂检验表",//wuliao
40 : "成品检验表",//p
50 : "首件检查表",//wp
},
materialTypes: {
"1": '成品',
"2": '半成品',
"3": '主要原料',
"4": '辅助材料',
"5": '加工工具',
"6": '辅助工装',
},
canvas: null,
ctx: null,
@ -693,15 +723,21 @@
judgeList: [],
limitedPhoto: false,
isDisabled: true,
type:null,
};
},
computed: {},
watch: {},
created() {
this.material = this.$route.params.id;
this.recordformLists();
},
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) => {
if (response.data) {
this.formList = response.data;
@ -709,6 +745,19 @@
});
},
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) {
this.dialogVisibleForm = value;
},
@ -795,7 +844,7 @@
}
},
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() {
@ -805,16 +854,23 @@
removeDomain(index) {
this.field_choice.splice(index, 1);
},
handleLook(scope) {
async handleLook(scope) {
debugger;
let that = this;
this.dialogFieldList=[];
that.tableForm = Object.assign({}, scope.row); // copy obj
that.formID = that.tableForm.id;
that.listQueryfield.form = that.formID;
getrffieldList(that.listQueryfield).then((response) => {
if (response.data) {
this.hasPicture = false;
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 => {
return item.field_type === 'draw'
});
@ -837,12 +893,8 @@
that.$set(that.checkForm, key, '')
}
that.dialogVisibleForm = true;
/* setTimeout(function () {
that.canvasInit();
}, 500);*/
}
});
that.fieldLists();
},
checkPermission,
handleCurrentChange(row) {
@ -851,13 +903,32 @@
this.fieldLists1();
},
recordformLists() {
this.listQueryrecordform.material = this.material;
// this.listQueryrecordform.type = 2;
getrecordformList(this.listQueryrecordform).then((response) => {
if (response.data) {
this.recordformList = response.data;
}
});
debugger;
let that = this;
that.listQueryrecordform.material = that.material;
if(that.type===10){
debugger;
that.listQueryrecordform.type = 10;
getrecordformList(that.listQueryrecordform).then((response) => {
if (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() {
let that = this;
@ -927,6 +998,14 @@
this.recordform = Object.assign({}, scope.row); // copy obj
this.dialogType = "edit";
this.dialogVisible = true;
if (this.recordform.export_template) {
this.fileList = [
{
name: this.recordform.export_template,
url: this.recordform.export_template,
},
];
}
this.$nextTick(() => {
this.$refs["Forms"].clearValidate();
});
@ -979,6 +1058,7 @@
obj.name=this.recordform.name;
obj.type=this.recordform.type;
obj.enabled=this.recordform.enabled;
obj.export_template=this.recordform.export_template?this.recordform.export_template:'';
if (isEdit) {
obj.form=this.recordform.form?this.recordform.form:null;
updaterecordform(this.recordform.id, obj).then(

View File

@ -14,9 +14,9 @@
border
fit
stripe
max-height="620"
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 label="工序编号">

View File

@ -216,8 +216,7 @@
}, {
value: '',
label: ''
},
{
}, {
value: '',
label: ''
}, {
@ -226,6 +225,27 @@
}, {
value: '',
label: ''
}, {
value: 'g',
label: 'g'
}, {
value: 'kg',
label: 'kg'
}, {
value: '',
label: ''
}, {
value: '',
label: ''
}, {
value: '',
label: ''
}, {
value: '',
label: ''
},{
value: '',
label: ''
},
],
listQuery: {
@ -268,7 +288,21 @@
},
//检查表
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() {
this.listQuery.page = 1;

View File

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

View File

@ -2,12 +2,13 @@
<div class="app-container">
<el-card>
<div slot="header" class="clearfix">
<span style="font-size: 16px;
<span style="font-size: 16px;
font-weight: 700;
">子工序列表</span>
</div>
<el-button type="primary" icon="el-icon-plus" @click="handleCreateStep"
>新增子工序</el-button>
>新增子工序
</el-button>
<el-table
v-loading="listLoading"
:data="stepList"
@ -18,7 +19,7 @@
max-height="600"
@row-click="rowClick"
>
<el-table-column type="index" width="50" />
<el-table-column type="index" width="50"/>
<el-table-column label="子工序名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
@ -27,18 +28,19 @@
</el-table-column>
<el-table-column label="相关设备">
<template slot-scope="scope" v-if="scope.row.equipments">
<el-tag v-for="item in scope.row.equipments_"
:key="item.number"
:label="item.name"
:value="item.number">{{item.name}}</el-tag>
<el-tag
v-for="item in scope.row.equipments_"
:key="item.number"
:label="item.name"
:value="item.number"
>
{{item.name}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="子工序类型">
<template slot-scope="scope"> {{ type_[scope.row.type] }}</template>
<el-table-column label="子工序类型">
<template slot-scope="scope">{{ type_[scope.row.type] }}</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
@ -46,17 +48,17 @@
>
<template slot-scope="scope">
<el-link
v-if="checkPermission(['step_update'])"
type="primary"
@click="handleEditStep(scope)"
>编辑</el-link
>
编辑
</el-link>
<el-link
v-if="checkPermission(['step_delete'])"
type="danger"
@click="handleDeleteStep(scope)"
>删除</el-link
>
删除
</el-link>
</template>
</el-table-column>
</el-table>
@ -73,40 +75,36 @@
:rules="rule1"
>
<el-form-item label="工序名称" prop="name">
<el-input v-model="step.name" placeholder="工序名称" />
<el-input v-model="step.name" placeholder="工序名称"/>
</el-form-item>
<el-form-item label="步骤编号" prop="number">
<el-input v-model="step.number" placeholder="工序编号" />
<el-input v-model="step.number" placeholder="工序编号"/>
</el-form-item>
<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
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<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 label="子工序类型" prop="type">
<el-select style="width: 100%" v-model="step.type" placeholder="请选择">
<el-form-item label="子工序类型" prop="type">
<el-select style="width: 100%" v-model="step.type" placeholder="请选择">
<el-option
v-for="item in typeoption"
:key="item.value"
:label="item.label"
:value="item.value">
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisibles = false">取消</el-button>
@ -116,15 +114,20 @@
</el-card>
<el-card>
<el-row :gutter="2">
<el-col :span="9" >
<el-card >
<el-col :span="9">
<el-card>
<div slot="header" class="clearfix">
<span style="font-size: 16px;
<span style="font-size: 16px;
font-weight: 700;
">过程记录表</span>
</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
:data="recordformList.results"
border
@ -135,17 +138,18 @@
v-el-height-adaptive-table="{bottomOffset: 50}"
@current-change="handleCurrentChange"
>
<el-table-column type="index" width="50" />
<el-table-column label="名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
<el-table-column type="index" width="50"/>
<el-table-column label="名称" prop="name"></el-table-column>
<el-table-column label="关联产品">
<template slot-scope="scope" v-if="scope.row.material_">{{ scope.row.material_.name }}</template>
</el-table-column>
<el-table-column label="状态">
<template slot-scope="scope">
<el-tag v-if="scope.row.enabled==true" >启用</el-tag>
<el-tag v-else>禁用</el-tag>
</template>
<el-table-column label="状态">
<template slot-scope="scope">
<el-tag v-if="scope.row.enabled==true">启用</el-tag>
<el-tag v-else>禁用</el-tag>
</template>
</el-table-column>
<el-table-column label="文件号">
<el-table-column label="文件号">
<template slot-scope="scope">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column
@ -154,20 +158,20 @@
>
<template slot-scope="scope">
<el-link
v-if="checkPermission(['material_update'])"
type="primary"
@click="handleLook(scope)"
>查看</el-link>
>查看
</el-link>
<el-link
v-if="checkPermission(['material_update'])"
type="primary"
@click="handleEdit(scope)"
>编辑</el-link>
>编辑
</el-link>
<el-link
v-if="checkPermission(['material_delete'])"
type="danger"
@click="handleDelete(scope)"
>删除</el-link>
>删除
</el-link>
</template>
</el-table-column>
</el-table>
@ -182,31 +186,54 @@
label-width="80px"
label-position="right"
>
<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 label="文件号" prop="number">
<el-input v-model="recordform.number" placeholder="文件号" />
<el-form-item label="文件号" prop="number">
<el-input v-model="recordform.number" placeholder="文件号"/>
</el-form-item>
<el-form-item label="状态">
<el-switch v-model="recordform.enabled"></el-switch>
</el-form-item>
<el-form-item label="状态">
<el-switch v-model="recordform.enabled"></el-switch>
</el-form-item>
<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
v-for="item in typeoptions"
:key="item.value"
: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-select>
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
@ -214,84 +241,104 @@
</div>
</el-dialog>
<el-dialog
class="bigDialog"
:model="tableForm"
:close-on-click-modal="false"
:visible.sync="dialogVisibleForm"
:title="tableForm.name">
:title="tableForm.name"
>
<el-form
label-width="80px"
label-width="200px"
label-position="right"
>
<el-row v-for="(item,$index) in fieldList.results" :key="$index">
<el-form-item v-if="item.field_type==='string'" :label="item.field_name" >
<el-input placeholder="请输入" v-model="item.sort"/>
</el-form-item>
<el-form-item v-else-if="item.field_type==='int'" :label="item.field_name">
<el-input type="number" placeholder="请输入" v-model="item.sort"/>
</el-form-item>
<el-form-item v-else-if="item.field_type==='float'" :label="item.field_name">
<el-input type="number" placeholder="请输入" v-model="item.sort"/>
</el-form-item>
<el-form-item v-else-if="item.field_type==='date'" :label="item.field_name">
<el-date-picker
v-model="item.create_time"
type="date"
placeholder="选择日期"
value-format="yyyy-MM-dd"
style="width:100%"
>
</el-date-picker>
</el-form-item>
<el-form-item v-else-if="item.field_type==='datetime'" :label="item.field_name">
<el-date-picker
v-model="item.create_time"
type="datetime"
placeholder="选择日期"
value-format="yyyy-MM-dd HH:mm:ss"
style="width:100%"
>
</el-date-picker>
</el-form-item>
<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-option
v-for="item1 in item.field_choice"
:key="item1"
:label="item1"
:value="item1">
</el-option>
</el-select>
</el-form-item>
<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-option
v-for="item1 in item.field_choice"
:key="item1"
:label="item1"
:value="item1">
</el-option>
</el-select>
</el-form-item>
<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-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 v-else-if="item.field_type==='int'" :label="item.field_name">
<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 v-else-if="item.field_type==='float'" :label="item.field_name">
<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 v-else-if="item.field_type==='date'" :label="item.field_name">
<el-date-picker
v-model="item.low_limit"
type="date"
placeholder="选择日期"
value-format="yyyy-MM-dd"
style="width:100%"
>
</el-date-picker>
<span v-if="item.help_text!==''&&item.help_text">{{item.help_text}}</span>
</el-form-item>
<el-form-item v-else-if="item.field_type==='datetime'" :label="item.field_name">
<el-date-picker
v-model="item.low_limit"
type="datetime"
placeholder="选择日期"
value-format="yyyy-MM-dd HH:mm:ss"
style="width:100%"
>
</el-date-picker>
<span v-if="item.help_text!==''&&item.help_text">{{item.help_text}}</span>
</el-form-item>
<el-form-item v-else-if="item.field_type==='select'" :label="item.field_name">
<el-select style="width: 100%" placeholder="请选择">
<el-option
v-model="item.low_limit"
v-for="item1 in item.field_choice"
:key="item1"
:label="item1"
:value="item1">
</el-option>
</el-select>
<span v-if="item.help_text!==''&&item.help_text">{{item.help_text}}</span>
</el-form-item>
<el-form-item v-else-if="item.field_type==='selects'" :label="item.field_name">
<el-select style="width: 100%" multiple placeholder="请选择">
<el-option
v-model="item.low_limit"
v-for="item1 in item.field_choice"
:key="item1"
:label="item1"
:value="item1">
</el-option>
</el-select>
<span v-if="item.help_text!==''&&item.help_text">{{item.help_text}}</span>
</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-form>
<!--<div style="text-align: right">-->
<!--<el-button type="danger">取消</el-button>-->
<!--<el-button type="primary">确认</el-button>-->
<!--</div>-->
</el-dialog>
</el-card>
</el-col>
<el-col :span="15" >
<el-card >
<el-col :span="15">
<el-card>
<div slot="header" class="clearfix">
<span style="font-size: 16px;
<span style="font-size: 16px;
font-weight: 700;
">记录字段</span>
</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
:data="fieldList.results"
border
fit
@ -299,61 +346,57 @@
highlight-current-row
height="100"
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">{{ options_[scope.row.field_type] }}</template>
</el-table-column>
<el-table-column label="字段名称">
<template slot-scope="scope">{{ scope.row.field_name }}</template>
</el-table-column>
<el-table-column label="字段标识">
<template slot-scope="scope">{{ scope.row.field_key }}</template>
</el-table-column>
<el-table-column label="选项显示名">
<template slot-scope="scope">{{ scope.row.field_choice }}</template>
</el-table-column>
<el-table-column label="字段说明">
<template slot-scope="scope">{{ scope.row.help_text }}</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
>
<template slot-scope="scope">
<el-link
v-if="checkPermission(['material_update'])"
type="primary"
@click="handlefieldEdit(scope)"
>编辑</el-link
>
编辑
</el-link>
<el-link
v-if="checkPermission(['material_delete'])"
type="danger"
@click="handlefieldDelete(scope)"
>删除</el-link
>
删除
</el-link>
</template>
</el-table-column>
</el-table>
<pagination
v-show="fieldList.count > 0"
:total="fieldList.count"
:page.sync="listQueryfield.page"
:limit.sync="listQueryfield.page_size"
@pagination="fieldLists"
/>
<el-dialog :visible.sync="dialogVisible1" :close-on-click-modal="false" :title="dialogType1 === 'edit' ? '编辑表格字段' : '新增表格字段'">
<pagination
v-show="fieldList.count > 0"
:total="fieldList.count"
:page.sync="listQueryfield.page"
:limit.sync="listQueryfield.page_size"
@pagination="fieldLists"
/>
<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-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="请选择">
<el-option
v-for="item in fieldtypeoptions"
:key="item.value"
@ -363,27 +406,52 @@
</el-select>
</el-form-item>
<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 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 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;">
<i class="el-icon-circle-plus-outline"></i>
<span style="font-size:14px;">添加</span>
</el-button>
<el-row v-for="(domain, $index) in field_choice" :key=domain+$index style="margin-bottom: 10px">
<el-col :span="20">
<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 :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-row>
</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-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>
<div style="text-align: right">
@ -399,63 +467,73 @@
</template>
<script>
import { getStepLists, createStep,updateStep,deleteStep } from "@/api/mtm";
import {getStepLists, createStep, updateStep, deleteStep,getMaterialList} from "@/api/mtm";
import checkPermission from "@/utils/permission";
import { getEquipmentAll } from "@/api/equipment";
import { upUrl, upHeaders } from "@/api/file";
import { getStep,getrecordformList,createrecordform,updaterecordform,deleterecordform,getrffieldList,createrffield,updaterffield,
deleterffield} from "@/api/mtm";
import {getEquipmentAll} from "@/api/equipment";
import {upUrl, upHeaders} from "@/api/file";
import {
getrecordformList,
createrecordform,
updaterecordform,
deleterecordform,
getrffieldList,
createrffield,
updaterffield,
deleterffield
} from "@/api/mtm";
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
const defaultstep = {
name: "",
number: "",
type:null,
type: null,
};
const defaultrecordform = {
enabled:true
};
const defaultfield = {
enabled: true
};
const defaultfield = {};
const defaultfield1 = {field_type: '', field_key: '', field_name: '', sort: '', field_choice: [""],};
export default {
components: { Pagination,vueJsonEditor },
components: {Pagination, vueJsonEditor},
data() {
return {
step: defaultstep,
stepList:[],
stepList: [],
dialogFieldList: [],
productOptions: [],
upHeaders: upHeaders(),
upUrl: upUrl(),
fileList:{
count: 0,
},
fileList: {
count: 0,
},
listLoading: true,
dialogVisibles: false,
dialogVisibleForm: false,
dialogTypes: "new",
field: {
field_type:'',
field_key:'',
field_name:'',
sort:'',
field_choice:[""],
field_type: '',
field_key: '',
field_name: '',
sort: '',
field_choice: [""],
draw_template:''
},
field_choice:[''],
options:[],
optio:[],
field_choice: [''],
options: [],
optio: [],
rule1: {
name: [{ required: true, message: "请输入", trigger: "blur" }],
number: [{ required: true, message: "请输入", trigger: "blur" }],
name: [{required: true, message: "请输入", trigger: "blur"}],
number: [{required: true, message: "请输入", trigger: "blur"}],
},
recordform: defaultrecordform,
dialogType: "new",
dialogVisible:false,
dialogVisible: false,
dialogType1: "new",
dialogVisible1:false,
tableForm:{
name:'',
dialogVisible1: false,
tableForm: {
name: '',
},
listQueryrecordform: {
page: 1,
@ -472,19 +550,20 @@
page_size: 20,
},
type_: {
1:'常规',
2:'分割',
3:'结合',
1: '常规',
2: '分割',
3: '结合',
},
options_: {
'string':'文本',
'int':'整数',
'float':'小数',
'string': '文本',
'int': '整数',
'float': '小数',
'date': '日期',
'datetime': '日期时间',
'select': '单选',
'selects': '多选',
'draw': '绘图模板',
},
typeoption: [{
value: 1,
@ -529,10 +608,15 @@
{
value: 'selects',
label: '多选'
},
{
value: 'draw',
label: '绘图模板'
}
],
formList:[],
typeoptions: [{
value: 1,
value: 10,
label: '生产记录'
}],
};
@ -543,24 +627,41 @@
this.step.process = this.$route.params.id;
this.getList();
this.getequipments()
},
mounted(){
this.step.process = this.$route.params.id;
this.getProductList();
this.getFormList();
},
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('')
},
//删除字段选项
removeDomain(index){
removeDomain(index) {
this.field_choice.splice(index, 1)
},
handleLook(scope){
debugger;
console.log(scope);
handleLook(scope) {
this.dialogVisibleForm = true;
this.tableForm = Object.assign({}, scope.row); // copy obj
this.formID=this.tableForm.id;
this.fieldLists();
this.dialogFieldList = [];
this.tableForm = Object.assign({}, scope.row);
this.formID = this.tableForm.id;
getrffieldList({page:0,form:this.formID}).then((response) => {
if (response.data) {
this.dialogFieldList = response.data;
}
});
},
checkPermission,
//子工序列表
@ -591,13 +692,10 @@
handleUpSuccess(res, file, filelist) {
this.step.instruction = res.data.id;
},
handleRemove(file, filelist){
handleRemove(file, filelist) {
this.step.instruction = null;
},
handleFilter() {
this.listQuery.page = 1;
this.getList();
@ -618,9 +716,9 @@
this.$refs["Form"].clearValidate();
});
},
rowClick(row) {
this.stepid= row.id ;
rowClick(row) {
this.stepid = row.id;
this.recordformLists();
},
@ -633,6 +731,7 @@
this.$refs["Form"].clearValidate();
});
},
handleDeleteStep(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
@ -663,7 +762,6 @@
}
});
} else {
console.log(this.step)
createStep(this.step).then((res) => {
if (res.code >= 200) {
this.getList();
@ -677,50 +775,74 @@
}
});
},
handleCurrentChange(row){
this.formID=row.id;
this.fieldLists();
handleCurrentChange(row) {
this.formID = row.id;
this.fieldLists();
},
recordformLists()
{
this.listQueryrecordform.step=this.stepid;
this.listQueryrecordform.type=10;
recordformLists() {
this.listQueryrecordform.step = this.stepid;
this.listQueryrecordform.type = 10;
getrecordformList(this.listQueryrecordform).then((response) => {
if (response.data) {
this.recordformList = response.data;
}
});
},
fieldLists()
{
this.listQueryfield.form=this.formID
getFormList(){
getrecordformList({page:0,type:10}).then((response) => {
if (response.data) {
this.formList = response.data;
}
});
},
fieldLists() {
this.listQueryfield.form = this.formID;
getrffieldList(this.listQueryfield).then((response) => {
if (response.data) {
this.fieldList = response.data;
debugger;
console.log(this.fieldList)
}
});
},
//新增记录表
handleCreate() {
this.recordform = Object.assign({}, defaultrecordform);
this.dialogType = "new";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Forms"].clearValidate();
});
if(this.stepid!==''&&this.stepid!==null&&this.stepid!==undefined){
this.recordform = Object.assign({}, defaultrecordform);
this.dialogType = "new";
this.dialogVisible = true;
this.$nextTick(() => {
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() {
this.field_choice = [''];
this.field = Object.assign({}, defaultfield);
this.field = Object.assign({}, defaultfield1);
this.dialogType1 = "new";
this.dialogVisible1 = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
@ -750,7 +872,7 @@
})
.then(async () => {
await deleterecordform(scope.row.id);
this.recordformLists()
this.recordformLists();
this.$message.success("成功");
})
.catch((err) => {
@ -765,7 +887,7 @@
})
.then(async () => {
await deleterffield(scope.row.id);
this.fieldLists()
this.fieldLists();
this.$message.success("成功");
})
.catch((err) => {
@ -777,21 +899,19 @@
if (valid) {
const isEdit = this.dialogType === "edit";
if (isEdit) {
this.recordform.step=this.stepid
this.recordform.step = this.stepid;
updaterecordform(this.recordform.id, this.recordform).then((res) => {
if (res.code >= 200) {
this.recordformLists()
this.recordformLists();
this.dialogVisible = false;
this.$message.success("成功");
}
});
} else {
this.recordform.step=this.stepid
this.recordform.step = this.stepid;
createrecordform(this.recordform).then((res) => {
if (res.code >= 200) {
this.recordformLists()
this.recordformLists();
this.dialogVisible = false;
this.$message.success("成功");
}
@ -807,21 +927,21 @@
if (valid) {
const isEdit = this.dialogType1 === "edit";
if (isEdit) {
this.field.form=this.formID;
this.field.form = this.formID;
this.field.field_choice = this.field_choice;
updaterffield(this.field.id, this.field).then((res) => {
if (res.code >= 200) {
this.fieldLists()
this.fieldLists();
this.dialogVisible1 = false;
this.$message.success("成功");
}
});
} else {
this.field.form=this.formID;
this.field.form = this.formID;
this.field.field_choice = this.field_choice;
createrffield(this.field).then((res) => {
if (res.code >= 200) {
this.fieldLists()
this.fieldLists();
this.dialogVisible1 = false;
this.$message.success("成功");
}

View File

@ -190,8 +190,7 @@
}, {
value: '',
label: ''
},
{
}, {
value: '',
label: ''
}, {
@ -200,6 +199,27 @@
}, {
value: '',
label: ''
}, {
value: 'g',
label: 'g'
}, {
value: 'kg',
label: 'kg'
}, {
value: '',
label: ''
}, {
value: '',
label: ''
}, {
value: '',
label: ''
}, {
value: '',
label: ''
},{
value: '',
label: ''
},
],
listQuery: {
@ -241,7 +261,21 @@
},
//检查表
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() {
this.listQuery.page = 1;

View File

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

View File

@ -33,7 +33,7 @@
fit
stripe
style="width: 100%"
height="300"
:height="domHeight"
@row-click="tableRowClick"
>
<el-table-column type="index" width="50"/>
@ -96,7 +96,7 @@
@pagination="getplanList"
/>
</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>
<gantt
v-if="proList.length>0"
@ -116,6 +116,7 @@
components: {Pagination, gantt},
data() {
return {
domHeight:null,
productionplanList: {
count: 0,
},
@ -279,6 +280,11 @@
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>

View File

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

View File

@ -30,15 +30,10 @@
</template>
</el-table-column>
<el-table-column label="产品状态">
<template slot-scope="scope">{{
actstate_[scope.row.act_state]
}}
</template>
<template slot-scope="scope">{{actstate_[scope.row.act_state]}}</template>
</el-table-column>
<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 label="最后检验结果">
<template slot-scope="scope">
@ -58,7 +53,6 @@
>
<template slot-scope="scope">
<el-link
v-if="checkPermission(['material_delete'])"
type="primary"
@click="handleoption(scope)"
>生成流程卡
@ -106,7 +100,7 @@
<el-col v-for="item in fieldList" :key="item.id" :span="24">
<div class="items" v-if="item.field_type==='draw'" style="height: 400px">
<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>
</el-col>
</el-row>

View File

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

View File

@ -1,100 +1,97 @@
<template>
<div class="app-container">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>生产任务列表</span>
</div>
<el-table
<div slot="header" class="clearfix">
<span>生产任务列表</span>
</div>
<el-table
:data="subproductionplanList.results"
fit
style="width: 100%"
height="100"
stripe
border
v-el-height-adaptive-table="{bottomOffset: 50}"
stripe
border
v-el-height-adaptive-table="{bottomOffset: 50}"
>
<el-table-column type="index" width="50" />
<el-table-column label="子计划编号" width="100px">
<template slot-scope="scope">{{scope.row.number}}</template>
</el-table-column>
<el-table-column label="产品名称" width="180px" >
<el-table-column type="index" width="50"/>
<el-table-column label="子计划编号" width="100px">
<template slot-scope="scope">{{scope.row.number}}</template>
</el-table-column>
<el-table-column label="产品名称" width="180px">
<template slot-scope="scope" v-if="scope.row.product_">{{ scope.row.product_.name }}</template>
</el-table-column>
<el-table-column label="产品型号" >
<el-table-column label="产品型号">
<template slot-scope="scope" v-if="scope.row.product_">{{ scope.row.product_.specification }}</template>
</el-table-column>
<el-table-column label="名称" width="160px">
<template slot-scope="scope" v-if="scope.row.subproduction_">{{ scope.row.subproduction_.name }}</template>
<el-table-column label="名称" width="160px">
<template slot-scope="scope" v-if="scope.row.subproduction_">{{ scope.row.subproduction_.name }}</template>
</el-table-column>
<el-table-column label="工序名" >
<template slot-scope="scope" v-if="scope.row.process_" >{{ scope.row.process_.name }}</template>
<el-table-column label="工序名">
<template slot-scope="scope" v-if="scope.row.process_">{{ scope.row.process_.name }}</template>
</el-table-column>
<el-table-column label="工序编号">
<template slot-scope="scope" v-if="scope.row.process_">{{ scope.row.process_.number }}</template>
<el-table-column label="工序编号">
<template slot-scope="scope" v-if="scope.row.process_">{{ scope.row.process_.number }}</template>
</el-table-column>
<el-table-column label="子工序" width="200">
<template slot-scope="scope" v-if="scope.row.steps">
<el-table-column label="子工序" width="200">
<template slot-scope="scope" v-if="scope.row.steps">
<el-tag v-for="item in scope.row.steps"
:key="item.number"
:label="item.name"
:value="item.number">{{item.name}}</el-tag>
:value="item.number"
>
{{item.name}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="生产车间" width="100px">
<template slot-scope="scope" v-if="scope.row.workshop_">{{ scope.row.workshop_.name }}</template>
<el-table-column label="生产车间" width="100px">
<template slot-scope="scope" v-if="scope.row.workshop_">{{ scope.row.workshop_.name }}</template>
</el-table-column>
<el-table-column label="生产数量">
<el-table-column label="生产数量">
<template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column>
<el-table-column label="开工时间" width="100px">
<el-table-column label="开工时间" width="100px">
<template slot-scope="scope">{{ scope.row.start_date }}</template>
</el-table-column>
<el-table-column label="完工时间" width="100px">
<el-table-column label="完工时间" width="100px">
<template slot-scope="scope">{{ scope.row.end_date }}</template>
</el-table-column>
<el-table-column label="下达状态">
<el-table-column label="下达状态">
<template slot-scope="scope">{{ state_[scope.row.state] }}</template>
</el-table-column>
<el-table-column label="创建时间" width="160px">
<el-table-column label="创建时间" width="160px">
<template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
width="100px"
fixed="right"
fixed="right"
>
<template slot-scope="scope">
<el-link type="primary"
v-if="checkPermission(['warehouse_update'])"
<el-link
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)"
>修改日期</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)"
>下达</el-link
>
<el-link type="primary"
v-if="checkPermission(['warehouse_update'])"
下达
</el-link>
<el-link
type="primary"
@click="handleselectclick(scope)"
>查看详情</el-link
>
查看详情
</el-link>
</template>
</el-table-column>
</el-table>
<pagination
<pagination
v-show="subproductionplanList.count > 0"
:total="subproductionplanList.count"
:page.sync="listQuery.page"
@ -124,7 +121,7 @@
</el-date-picker>
</el-form-item>
<el-form-item label="子计划完工时间" prop="end_date">
<el-date-picker
<el-date-picker
v-model="subproductionplan.end_date"
type="date"
placeholder="选择日期"
@ -133,223 +130,208 @@
>
</el-date-picker>
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirm('Form')">确认</el-button>
</div>
</el-dialog>
<el-dialog
<el-dialog
:visible.sync="dialogVisibles"
:close-on-click-modal="false"
>
<el-table
<el-table
:data="xhwl"
border
border
fit
stripe
style="width: 100%"
max-height="400"
>
<el-table-column type="index" width="50" />
<el-table-column label="预计消耗">
<el-table-column type="index" width="50"/>
<el-table-column label="预计消耗">
<template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column>
<el-table-column label="实际消耗">
<el-table-column label="实际消耗">
<template slot-scope="scope">{{ scope.row.count_real }}</template>
</el-table-column>
<el-table-column label="生产计划编号">
<template slot-scope="scope">{{ scope.row.subproduction_plan_.number }}</template>
</el-table-column>
<el-table-column label="物料名称">
<el-table-column label="物料名称">
<template slot-scope="scope">{{ scope.row.material_.name }}</template>
</el-table-column>
<el-table-column label="物料编号">
<el-table-column label="物料编号">
<template slot-scope="scope">{{ scope.row.material_.number }}</template>
</el-table-column>
<el-table-column label="物料型号">
<el-table-column label="物料型号">
<template slot-scope="scope">{{ scope.row.material_.specification }}</template>
</el-table-column>
<el-table-column label="物料单位">
<el-table-column label="物料单位">
<template slot-scope="scope">{{ scope.row.material_.unit }}</template>
</el-table-column>
</el-table>
<el-table
<el-table
:data="ccwl"
border
border
fit
stripe
style="width: 100%"
max-height="400"
>
<el-table-column type="index" width="50" />
<el-table-column label="预计产出">
<el-table-column type="index" width="50"/>
<el-table-column label="预计产出">
<template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column>
<el-table-column label="实际产出">
<el-table-column label="实际产出">
<template slot-scope="scope">{{ scope.row.count_real }}</template>
</el-table-column>
<el-table-column label="生产计划编号">
<template slot-scope="scope">{{ scope.row.subproduction_plan_.number }}</template>
</el-table-column>
<el-table-column label="物料名称">
<el-table-column label="物料名称">
<template slot-scope="scope">{{ scope.row.material_.name }}</template>
</el-table-column>
<el-table-column label="物料编号">
<el-table-column label="物料编号">
<template slot-scope="scope">{{ scope.row.material_.number }}</template>
</el-table-column>
<el-table-column label="物料型号">
<el-table-column label="物料型号">
<template slot-scope="scope">{{ scope.row.material_.specification }}</template>
</el-table-column>
<el-table-column label="物料单位">
<el-table-column label="物料单位">
<template slot-scope="scope">{{ scope.row.material_.unit }}</template>
</el-table-column>
</el-table>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisibles = false">取消</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getsubproductionplanList,updatesubproductionplan,getProgress,issuesubplan } from "@/api/pm";
import checkPermission from "@/utils/permission";
<script>
import {getsubproductionplanList, updatesubproductionplan, getProgress, issuesubplan} from "@/api/pm";
import checkPermission from "@/utils/permission";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaultesubproductionplan = {
};
export default {
components: { Pagination },
data() {
return {
subproductionplan: defaultesubproductionplan,
subproductionplanList: {
count: 0,
},
listQuery: {
page: 1,
page_size: 20,
},
xhwl:[],
ccwl:[],
listLoading: true,
dialogVisible: false,
dialogVisibles: false,
dialogType: "new",
rule1: {
number: [{ required: true, message: "请输入", trigger: "blur" }],
},
state_:{
10:'制定中',
20:'已下达',
30:'已接受',
40:'生产中',
50:'已完成'}
};
},
computed: {},
watch: {},
created() {
this.id=this.$route.params.id;
this.getspList();
},
methods: {
checkPermission,
//订单列表
getspList() {
this.listLoading = true;
this.listQuery.production_plan = this.id;
console.log(this.listQuery)
getsubproductionplanList(this.listQuery).then((response) => {
if (response.data) {
this.subproductionplanList = response.data;
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaultesubproductionplan = {};
export default {
components: {Pagination},
data() {
return {
subproductionplan: defaultesubproductionplan,
subproductionplanList: {
count: 0,
},
listQuery: {
page: 1,
page_size: 20,
},
xhwl: [],
ccwl: [],
listLoading: true,
dialogVisible: false,
dialogVisibles: false,
dialogType: "new",
rule1: {
number: [{required: true, message: "请输入", trigger: "blur"}],
},
state_: {
10: '制定中',
20: '已下达',
30: '已接受',
40: '生产中',
50: '已完成',
60: "军检完成",
70: "暂停",
80: "终止",
}
this.listLoading = false;
});
};
},
handleclick(scope)
{
this.subproductionplan = Object.assign({}, scope.row); // copy obj
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
computed: {},
watch: {},
created() {
this.id = this.$route.params.id;
this.getspList();
},
methods: {
checkPermission,
//订单列表
getspList() {
this.listLoading = true;
this.listQuery.production_plan = this.id;
console.log(this.listQuery)
getsubproductionplanList(this.listQuery).then((response) => {
if (response.data) {
this.subproductionplanList = response.data;
}
this.listLoading = false;
});
},
handleclick(scope) {
this.subproductionplan = Object.assign({}, scope.row); // copy obj
this.dialogVisible = true;
handleselectclick(scope)
{
this.dialogVisibles = true;
this.xhwl=[];
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
this.ccwl=[];
getProgress(scope.row.id).then((res) => {
if (res.code >= 200) {
res.data.forEach((item) => {
if(item.type==1)
{
this.xhwl.push(item);
}
else if(item.type==2)
{
this.ccwl.push(item);
}
});
},
handleselectclick(scope) {
this.dialogVisibles = true;
this.xhwl = [];
this.ccwl = [];
getProgress(scope.row.id).then((res) => {
if (res.code >= 200) {
res.data.forEach((item) => {
if (item.type == 1) {
this.xhwl.push(item);
} else if (item.type == 2) {
this.ccwl.push(item);
}
});
},
confirm()
{
updatesubproductionplan(this.subproductionplan.id,this.subproductionplan).then((res) => {
if (res.code >= 200) {
this.getspList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
},
handleissuedclick(scope)
{
this.$confirm("确定下达子计划?", "提醒", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
})
.then(async () => {
await issuesubplan(scope.row.id).then((res) => {
});
}
});
},
confirm() {
updatesubproductionplan(this.subproductionplan.id, this.subproductionplan).then((res) => {
if (res.code >= 200) {
this.getspList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
},
handleissuedclick(scope) {
this.$confirm("确定下达子计划?", "提醒", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
})
.then(async () => {
await issuesubplan(scope.row.id).then((res) => {
if (res.code >= 200) {
this.getspList();
this.$message.success("子计划已下达!");
}
});
})
.catch((err) => {
console.error(err);
});
}
},
};
</script>
})
.catch((err) => {
console.error(err);
});
}
},
};
</script>

View File

@ -43,7 +43,6 @@
fit
stripe
highlight-current-row
max-height="700"
height="100"
v-el-height-adaptive-table="{ bottomOffset: 43 }"
>
@ -73,7 +72,7 @@
订单项
</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"
@click="handleAudit(scope)"
>

View File

@ -2,9 +2,13 @@
<div class="app-container">
<el-card>
<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>
</el-card>
<el-card style="margin-top: 2px">
@ -19,32 +23,33 @@
height="100"
v-el-height-adaptive-table="{ bottomOffset: 43 }"
>
<el-table-column type="index" width="50" />
<el-table-column label="物料名称">
<el-table-column type="index" width="50"/>
<el-table-column label="物料名称">
<template slot-scope="scope">{{ scope.row.material_.name }}</template>
</el-table-column>
<el-table-column label="物料型号">
<el-table-column label="物料型号">
<template slot-scope="scope">{{ scope.row.material_.specification }}</template>
</el-table-column>
<el-table-column label="采购数量">
<!--<el-table-column label="物料品牌">
<template slot-scope="scope">{{ scope.row.brand }}</template>
</el-table-column>-->
<el-table-column label="采购数量">
<template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column>
<el-table-column label="已到货数量">
<el-table-column label="已到货数量">
<template slot-scope="scope">{{ scope.row.delivered_count }}</template>
</el-table-column>
<el-table-column label="截止到货时间">
<el-table-column label="截止到货时间">
<template slot-scope="scope">{{ scope.row.delivery_date }}</template>
</el-table-column>
<el-table-column align="center" label="操作" width="220px">
<template slot-scope="scope">
<el-link
v-if="checkPermission(['vendor_delete'])"
type="danger"
@click="handleDelete(scope)"
>删除</el-link
>
删除
</el-link>
</template>
</el-table-column>
</el-table>
@ -65,10 +70,10 @@
:rules="rule1"
>
<el-form-item label="所需数量" prop="number">
<el-input v-model="puorderTtem.count" placeholder="所需数量" />
<el-input v-model="puorderTtem.count" placeholder="所需数量"/>
</el-form-item>
<el-form-item label="截止到货时间" prop="delivery_date">
<el-date-picker
<el-form-item label="截止到货时间" prop="delivery_date">
<el-date-picker
v-model="puorderTtem.delivery_date"
type="date"
placeholder="选择日期"
@ -88,6 +93,9 @@
</el-option>
</el-select>
</el-form-item>
<!--<el-form-item label="物料品牌">
<el-input v-model="puorderTtem.brand" placeholder="规格型号"/>
</el-form-item>-->
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
@ -97,101 +105,101 @@
</div>
</template>
<script>
import { getpVendorList } from "@/api/vendor";
import { getMaterialList } from "@/api/mtm";
import {getpVendorList} from "@/api/vendor";
import {getMaterialList} from "@/api/mtm";
import {
getPuorderItemList,
createPuorderItem,
deletePuorderItem,
} from "@/api/pum";
import checkPermission from "@/utils/permission";
import {
getPuorderItemList,
createPuorderItem,
deletePuorderItem,
} from "@/api/pum";
import checkPermission from "@/utils/permission";
import { genTree } from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaultpuorderItem = {
pu_order:null,
};
export default {
components: { Pagination },
data() {
return {
puorderTtem: defaultpuorderItem,
puorderTtemList: {
count: 0,
},
materialoptions: [],
listQuery: {
page: 1,
page_size: 20,
},
dialogVisible:false,
rule1: {
delivery_date: [{ required: true, message: "请选择日期", trigger: "blur" }],
material: [
{ required: true, message: "请选择物料", trigger: "change" },
],
},
};
},
computed: {},
watch: {},
created() {
this.id = this.$route.params.id;
this.getList();
this.getmaterialList();
},
methods: {
checkPermission,
//采购订单列表
getList() {
this.listQuery.pu_order= this.id;
getPuorderItemList(this.listQuery).then((response) => {
if (response.data) {
this.puorderTtemList = response.data;
}
});
import {genTree} from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaultpuorderItem = {
pu_order: null,
};
export default {
components: {Pagination},
data() {
return {
puorderTtem: defaultpuorderItem,
puorderTtemList: {
count: 0,
},
materialoptions: [],
listQuery: {
page: 1,
page_size: 20,
},
dialogVisible: false,
rule1: {
delivery_date: [{required: true, message: "请选择日期", trigger: "blur"}],
material: [
{required: true, message: "请选择物料", trigger: "change"},
],
},
};
},
//物料
getmaterialList() {
getMaterialList({ page: 0 }).then((response) => {
if (response.data) {
this.materialoptions = response.data;
}
});
computed: {},
watch: {},
created() {
this.id = this.$route.params.id;
this.getList();
this.getmaterialList();
},
handleCreate() {
this.puorderTtem = Object.assign({}, defaultpuorderItem);
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
async confirm() {
this.puorderTtem.pu_order=this.id
createPuorderItem(this.puorderTtem).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deletePuorderItem(scope.row.id);
this.getList();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
methods: {
checkPermission,
//采购订单列表
getList() {
this.listQuery.pu_order = this.id;
getPuorderItemList(this.listQuery).then((response) => {
if (response.data) {
this.puorderTtemList = response.data;
}
});
},
//物料
getmaterialList() {
getMaterialList({page: 0}).then((response) => {
if (response.data) {
this.materialoptions = response.data;
}
});
},
handleCreate() {
this.puorderTtem = Object.assign({}, defaultpuorderItem);
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
async confirm() {
this.puorderTtem.pu_order = this.id
createPuorderItem(this.puorderTtem).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deletePuorderItem(scope.row.id);
this.getList();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
});
},
},
},
};
};
</script>

View File

@ -43,9 +43,8 @@
fit
stripe
highlight-current-row
max-height="700"
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 label="供应商名" prop="name">
@ -56,8 +55,8 @@
</el-table-column>
<el-table-column label="地址" prop="address" min-width="120" show-overflow-tooltip>
</el-table-column>
<el-table-column label="供应物料" prop="material">
</el-table-column>
<!-- <el-table-column label="供应物料" prop="material">
</el-table-column>-->
<el-table-column label="备注" prop="description">
</el-table-column>
<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-tab-pane label="总览" name="1">
<el-table
v-loading="listLoading"
:data="fifodetailList1.results"
border
fit
stripe
highlight-current-row
height="620"
v-el-height-adaptive-table="{bottomOffset: 40}"
height="100"
v-el-height-adaptive-table="{bottomOffset: 42}"
>
<el-table-column type="index" width="50"/>
<el-table-column label="物料批次">
@ -57,7 +56,7 @@
<el-table-column label="创建时间">
<template slot-scope="scope">{{scope.row.create_time}}</template>
</el-table-column>
<el-table-column
<!-- <el-table-column
align="center"
label="操作"
>
@ -69,7 +68,7 @@
复验记录
</el-link>
</template>
</el-table-column>
</el-table-column>-->
</el-table>
<pagination
v-show="fifodetailList1.count > 0"
@ -87,8 +86,8 @@
fit
stripe
highlight-current-row
height="620"
v-el-height-adaptive-table="{bottomOffset: 40}"
height="100"
v-el-height-adaptive-table="{bottomOffset: 42}"
>
<el-table-column type="index" width="50"/>
<el-table-column label="物料批次">
@ -127,7 +126,7 @@
stripe
highlight-current-row
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 label="物料批次">
@ -164,7 +163,7 @@
<el-table-column label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column>
<el-table-column
<!--<el-table-column
align="center"
label="操作"
>
@ -185,7 +184,7 @@
复验记录
</el-link>
</template>
</el-table-column>
</el-table-column>-->
</el-table>
<pagination
v-show="fifodetailList3.count > 0"
@ -204,7 +203,7 @@
stripe
highlight-current-row
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 label="物料批次">
@ -235,7 +234,7 @@
<el-table-column label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column>
<el-table-column
<!--<el-table-column
align="center"
label="操作"
>
@ -256,7 +255,7 @@
复验记录
</el-link>
</template>
</el-table-column>
</el-table-column>-->
</el-table>
<pagination
v-show="fifodetailList4.count > 0"
@ -273,7 +272,7 @@
<script>
import {getfifodetailList} from "@/api/inm";
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
export default {

View File

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

View File

@ -7,7 +7,8 @@
fit
stripe
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 label="产品编号">
@ -111,6 +112,10 @@
@click="handleRecordDetail(scope)"
>查看
</el-link>
<el-link
@click="handleRecordExport(scope)"
>导出
</el-link>
</template>
</el-table-column>
</el-table>
@ -145,7 +150,7 @@
<el-col v-for="item in fieldList" :key="item.id" :span="24">
<div class="items" v-if="item.field_type==='draw'" style="height: 400px">
<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>
</el-col>
</el-row>
@ -154,11 +159,11 @@
</div>
</template>
<script>
import {getfifodetailList} from "@/api/inm";
// import {getfifodetailList} from "@/api/inm";
import checkPermission from "@/utils/permission";
import {mtest, getwproductList} from "@/api/wpm";
import {getrecordformList, getrffieldList} from "@/api/mtm";
import {getTestRecord, getTestRecordItem} from "@/api/qm";
// import {getrecordformList, getrffieldList} from "@/api/mtm";
import {getTestRecord, getTestRecordItem,getTestRecordExport} from "@/api/qm";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
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>

View File

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

View File

@ -48,6 +48,7 @@
<el-table-column align="center" label="操作">
<template slot-scope="scope">
<el-link @click="handleRecordDetail(scope)">查看</el-link>
<el-link @click="handleRecordExport(scope)">导出</el-link>
</template>
</el-table-column>
</el-table>
@ -79,7 +80,7 @@
<el-col v-for="item in fieldList" :key="item.id" :span="24">
<div class="items" v-if="item.field_type==='draw'" style="height: 400px">
<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>
</el-col>
</el-row>
@ -90,8 +91,7 @@
<script>
import checkPermission from "@/utils/permission";
import {getProductionplan} from "@/api/pm";
import {getTestRecord, getTestRecordItem} from "@/api/qm";
import {getTestRecord, getTestRecordItem,getTestRecordExport} from "@/api/qm";
export default {
data() {
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>

View File

@ -4,12 +4,14 @@
<el-tabs v-model="activeName" type="card">
<el-tab-pane label="成品不合格" name="1">
<el-table
v-loading="listLoading"
:data="wproductList.results"
border
fit
stripe
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 label="产品编号">
@ -70,8 +72,8 @@
fit
stripe
highlight-current-row
height="620"
v-el-height-adaptive-table="{ bottomOffset: 40 }"
height="100"
v-el-height-adaptive-table="{bottomOffset: 42}"
>
<el-table-column type="index" width="50"/>
<el-table-column label="玻璃编号">
@ -129,14 +131,13 @@
</el-tab-pane>
<el-tab-pane label="入厂不合格" name="4">
<el-table
v-loading="listLoading"
:data="fifodetailList4.results"
border
fit
stripe
highlight-current-row
height="620"
v-el-height-adaptive-table="{bottomOffset: 40}"
height="100"
v-el-height-adaptive-table="{bottomOffset: 42}"
>
<el-table-column type="index" width="50"/>
<el-table-column label="物料批次">
@ -274,7 +275,7 @@
<el-col v-for="item in recordFieldList" :key="item.id" :span="24">
<div class="items" v-if="item.field_type==='draw'" style="height: 400px">
<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>
</el-col>
</el-row>
@ -390,7 +391,7 @@
//不合格玻璃审理单查看
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,19 +1,19 @@
<template>
<div class="app-container">
<el-card style="margin-top: 2px">
<el-descriptions title="基本信息" :column="8" :size="size" border>
<el-descriptions-item label="合同名称" > {{contractdetail.name}}</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="客户名称" v-if="contractdetail.customer"> {{contractdetail.customer_.name}} </el-descriptions-item>
</el-descriptions>
</el-card>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>关联订单</span>
</div>
<el-table
<el-descriptions-item label="合同名称"> {{contractdetail.name}}</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="客户名称" v-if="contractdetail.customer"> {{contractdetail.customer_.name}}
</el-descriptions-item>
</el-descriptions>
</el-card>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>关联订单</span>
</div>
<el-table
v-loading="listLoading"
:data="OrderList"
border
@ -21,110 +21,102 @@
stripe
highlight-current-row
height="510px"
>
<el-table-column type="index" width="50" />
<el-table-column label="订单编号" width="160" show-overflow-tooltip>
<el-table-column type="index" width="50"/>
<el-table-column label="订单编号" width="160" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.number }}</template>
</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>
</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>
</el-table-column>
<el-table-column label="产品型号" width="120" show-overflow-tooltip>
<el-table-column label="产品型号" width="120" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.product_.specification }}</template>
</el-table-column>
<el-table-column label="产品数量" >
<el-table-column label="产品数量">
<template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column>
<el-table-column label="交货日期" >
<el-table-column label="交货日期">
<template slot-scope="scope">{{ scope.row.delivery_date }}</template>
</el-table-column>
<el-table-column label="已交货数量" >
<el-table-column label="已交货数量">
<template slot-scope="scope">{{ scope.row.delivered_count }}</template>
</el-table-column>
<el-table-column label="创建时间" width="160" >
<el-table-column label="创建时间" width="160">
<template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column>
<el-table-column
<el-table-column
align="center"
label="操作"
width="220px"
>
<template slot-scope="scope">
<el-link
v-if="checkPermission(['warehouse_delete'])"
type="primary"
<el-link
type="primary"
@click="handleDetail(scope)"
>详情</el-link
>
详情
</el-link>
</template>
</el-table-column>
</el-table>
</el-card>
</el-card>
</div>
</template>
<script>
import {getContract,getOrderList} from "@/api/sam";
import checkPermission from "@/utils/permission";
import {getContract, getOrderList} from "@/api/sam";
import checkPermission from "@/utils/permission";
import { genTree } from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
import {genTree} from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
export default {
components: { Pagination },
data() {
return {
contractdetail:"",
OrderList:"",
};
},
computed: {},
watch: {},
created() {
this.id = this.$route.params.id;
this.getdetail();
this.getList();
export default {
components: {Pagination},
data() {
return {
contractdetail: "",
OrderList: "",
},
methods: {
checkPermission,
getList() {
getOrderList({contract:this.id,page:0}).then((response) => {
if (response.data) {
this.OrderList = response.data;
}
})
};
},
//详情
getdetail() {
getContract(this.id).then((response) => {
if (response.data) {
this.contractdetail = response.data;
}
})
computed: {},
watch: {},
created() {
this.id = this.$route.params.id;
this.getdetail();
this.getList();
},
//订单详情
handleDetail(scope){
this.$router.push({name: "orderdetail", params: { id: scope.row.id }, })
}
},
};
methods: {
checkPermission,
getList() {
getOrderList({contract: this.id, page: 0}).then((response) => {
if (response.data) {
this.OrderList = response.data;
}
})
},
//详情
getdetail() {
getContract(this.id).then((response) => {
if (response.data) {
this.contractdetail = response.data;
}
})
},
//订单详情
handleDetail(scope) {
this.$router.push({name: "orderdetail", params: {id: scope.row.id},})
}
},
};
</script>

View File

@ -128,7 +128,7 @@
:rules="rule1"
>
<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 label="所需产品" prop="product">
<el-select style="width: 100%" v-model="order.product" placeholder="请选择">
@ -224,8 +224,9 @@
dialogVisible: false,
dialogType: "new",
rule1: {
product: [{required: true, message: "请输入", trigger: "blur"}],
delivery_date: [{required: true, message: "请输入", trigger: "blur"}],
number: [{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-descriptions title="基本信息" direction="vertical" :column="6" border>
<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">
{{ salesdetail.product_.name }}</el-descriptions-item
>
{{ salesdetail.product_.name }}
</el-descriptions-item>
<el-descriptions-item
v-if="salesdetail.product"
label="产品型号"
: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">
{{ salesdetail.order_.contract_.name }}</el-descriptions-item
>
{{ salesdetail.order_.contract_.name }}
</el-descriptions-item>
<el-descriptions-item label="合同编号" v-if="salesdetail.order">
{{ salesdetail.order_.contract_.number }}</el-descriptions-item
>
<el-descriptions-item label="订单编号" v-if="salesdetail.order">
{{ salesdetail.order_.contract_.number }}
</el-descriptions-item>
<el-descriptions-item label="订单编号" v-if="salesdetail.order">
{{ salesdetail.order_.number }}
</el-descriptions-item>
<el-descriptions-item label="物流详情" v-if="ship_pic!=''">
<el-link type="primary" :href="salesdetail.ship_pic">物流单</el-link></el-descriptions-item>
<el-descriptions-item v-if="ship_pic!=''" label="物流详情">
<el-link type="primary" :href="salesdetail.ship_pic">物流单</el-link>
</el-descriptions-item>
</el-descriptions>
<el-button type="primary" style="margin-top:10px" @click="upload">上传物流信息</el-button>
</el-card>
@ -40,38 +40,36 @@
highlight-current-row
style="width: 100%"
>
<el-table-column type="index" width="50" />
<el-table-column type="index" width="50"/>
<el-table-column label="产品编号" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="产品名称" show-overflow-tooltip>
<template slot-scope="scope">{{
scope.row.iproduct_.material_.name
}}</template>
<template slot-scope="scope">
{{scope.row.iproduct_.material_.name }}
</template>
</el-table-column>
<el-table-column label="批次">
<template slot-scope="scope">{{
scope.row.iproduct_.batch
}}</template>
<template slot-scope="scope">
{{scope.row.iproduct_.batch }}
</template>
</el-table-column>
<el-table-column label="仓库">
<template slot-scope="scope">{{
scope.row.iproduct_.warehouse_.name
}}</template>
<template slot-scope="scope">
{{scope.row.iproduct_.warehouse_.name }}
</template>
</el-table-column>
<el-table-column label="是否已军检">
<template slot-scope="scope">
<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 label="军检">
<template slot-scope="scope">
<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 label="装箱单号" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.packnum }}</template>
@ -82,60 +80,59 @@
<el-table-column align="center" label="操作" width="220px">
<template slot-scope="scope">
<el-link
v-if="checkPermission(['warehouse_delete'])"
type="primary"
@click="handlePack(scope)"
>装箱</el-link
>
装箱
</el-link>
<el-link
v-if="checkPermission(['warehouse_delete'])"
type="primary"
@click="handleNotPack(scope)"
>备注</el-link
>
备注
</el-link>
<el-link
v-if="checkPermission(['warehouse_delete'])"
type="danger"
@click="handleDelete(scope)"
>删除</el-link
>
删除
</el-link>
</template>
</el-table-column>
</el-table>
<el-dialog
:close-on-click-modal="false"
:visible.sync="dialogVisibless"
title="上传物流文件"
>
<el-form
ref="Forms"
:model="ship"
label-width="100px"
label-position="right"
:rules="rule1"
<el-dialog
:close-on-click-modal="false"
:visible.sync="dialogVisibless"
title="上传物流文件"
>
<el-form-item label="文件" prop="template" >
<el-upload
ref="upload"
:action="upUrl"
:on-preview="handlePreview"
:on-success="handleUpSuccess"
:on-remove="handleRemove"
:headers="upHeaders"
:file-list="fileList"
:limit="1"
accept=".webp,.bmp,.jpg,.png,.tif,.gif,.apng"
>
<el-button size="small" type="primary">上传文件</el-button>
</el-upload>
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisibless = false">取消</el-button>
<el-button type="primary" @click="uploadship">确认</el-button>
</div>
</el-dialog>
<el-form
ref="Forms"
:model="ship"
label-width="100px"
label-position="right"
:rules="rule1"
>
<el-form-item label="文件" prop="template">
<el-upload
ref="upload"
:action="upUrl"
:on-preview="handlePreview"
:on-success="handleUpSuccess"
:on-remove="handleRemove"
:headers="upHeaders"
:file-list="fileList"
:limit="1"
accept=".webp,.bmp,.jpg,.png,.tif,.gif,.apng"
>
<el-button size="small" type="primary">上传文件</el-button>
</el-upload>
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisibless = false">取消</el-button>
<el-button type="primary" @click="uploadship">确认</el-button>
</div>
</el-dialog>
<el-dialog
:visible.sync="dialogVisible"
:close-on-click-modal="false"
@ -149,9 +146,8 @@
label-position="right"
>
<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 label="装箱文件确认" prop="iproducts">
<el-table
:data="packlist"
@ -162,7 +158,7 @@
ref="multipleTable"
height="300"
>
<el-table-column type="index" width="50" label="序号" />
<el-table-column type="index" width="50" label="序号"/>
<el-table-column label="名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
@ -183,22 +179,22 @@
</template>
</el-table-column>
<el-table-column label="库存数量">
<template slot-scope="scope" v-if="scope.row.material_">{{
scope.row.material_.count
}}</template>
<template slot-scope="scope" v-if="scope.row.material_">
{{scope.row.material_.count}}
</template>
</el-table-column>
<el-table-column label="安全库存数量">
<template slot-scope="scope" v-if="scope.row.material_">{{
scope.row.material_.count_safe
}}</template>
<template slot-scope="scope" v-if="scope.row.material_">
{{scope.row.material_.count_safe}}
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
<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="submitPack">确认</el-button>
</div>
</el-dialog>
@ -215,13 +211,13 @@
label-position="right"
>
<el-form-item label="备注" prop="remark">
<el-input v-model="notpackData.remark" placeholder="未装箱备注" />
<el-input v-model="notpackData.remark" placeholder="未装箱备注"/>
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisibles = false"
>取消</el-button
>
<el-button type="danger" @click="dialogVisibles = false">
取消
</el-button>
<el-button type="primary" @click="submitnotPack">确认</el-button>
</div>
</el-dialog>
@ -229,63 +225,63 @@
</div>
</template>
<script>
import {
getSale,
getSaleproductList,
deleteSaleproduct,
gePack,
subPack,
notPackremark,
ship
} from "@/api/sam";
import checkPermission from "@/utils/permission";
import { upUrl, upHeaders } from "@/api/file";
import { genTree } from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaultepackData = {
packnum: "",
};
export default {
components: { Pagination },
data() {
return {
salesdetail: "",
saleproduct: "",
packlist: [],
upHeaders: upHeaders(),
import {
getSale,
getSaleproductList,
deleteSaleproduct,
gePack,
subPack,
notPackremark,
ship
} from "@/api/sam";
import checkPermission from "@/utils/permission";
import {upUrl, upHeaders} from "@/api/file";
import {genTree} from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaultepackData = {
packnum: "",
};
export default {
components: {Pagination},
data() {
return {
salesdetail: "",
saleproduct: "",
packlist: [],
upHeaders: upHeaders(),
upUrl: upUrl(),
dialogVisible: false,
dialogVisibles: false,
dialogVisibless: false,
ship:{},
packData: defaultepackData,
notpackData: { remark: "" },
detail: [],
fileList:[],
saleproductId: null,
saleProductid: null,
dialogType: "new",
};
},
computed: {},
watch: {},
created() {
this.id = this.$route.params.id;
this.getList();
this.getSaleproductLists();
},
methods: {
checkPermission,
//详情
getList() {
getSale(this.id).then((response) => {
if (response.data) {
this.salesdetail = response.data;
}
});
dialogVisible: false,
dialogVisibles: false,
dialogVisibless: false,
ship: {},
packData: defaultepackData,
notpackData: {remark: ""},
detail: [],
fileList: [],
saleproductId: null,
saleProductid: null,
dialogType: "new",
};
},
//上传物流文件
computed: {},
watch: {},
created() {
this.id = this.$route.params.id;
this.getList();
this.getSaleproductLists();
},
methods: {
checkPermission,
//详情
getList() {
getSale(this.id).then((response) => {
if (response.data) {
this.salesdetail = response.data;
}
});
},
//上传物流文件
handlePreview(file) {
if ("url" in file) {
window.open(file.url);
@ -295,95 +291,94 @@ export default {
},
handleUpSuccess(res, file, filelist) {
this.ship.path = res.data.path;
this.salesdetail.ship_pic=res.data.path;
this.salesdetail.ship_pic = res.data.path;
console.log(this.ship.path)
},
handleRemove(file, filelist){
handleRemove(file, filelist) {
this.ship.path = null;
},
upload() {
upload() {
this.dialogVisibless=true;
this.dialogVisibless = true;
},
},
uploadship()
{
console.log(this.ship);
ship(this.id, this.ship).then((res) => {
if (res.code >= 200) {
this.dialogVisibless = false;
this.$message.success("物流文件上传成功!");
}
});
},
uploadship() {
console.log(this.ship);
ship(this.id, this.ship).then((res) => {
if (res.code >= 200) {
getSaleproductLists() {
getSaleproductList({ sale: this.id, page: 0 }).then((response) => {
if (response.data) {
this.saleproduct = response.data;
}
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deleteSaleproduct(scope.row.id);
this.getSaleproductLists();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
this.dialogVisibless = false;
this.$message.success("物流文件上传成功!");
}
});
},
//装箱操作
handlePack(scope) {
this.packData = Object.assign({}, scope.row);
this.dialogType = "new";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
gePack(scope.row.id).then((response) => {
if (response.data) {
this.packlist = response.data.detail;
}
});
},
this.saleproductId = scope.row.id;
},
submitPack() {
this.packData.detail = this.packlist;
console.log(this.packData);
subPack(this.saleproductId, this.packData).then((res) => {
if (res.code >= 200) {
this.getSaleproductLists();
this.dialogVisible = false;
this.$message.success("成功");
}
});
getSaleproductLists() {
getSaleproductList({sale: this.id, page: 0}).then((response) => {
if (response.data) {
this.saleproduct = response.data;
}
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deleteSaleproduct(scope.row.id);
this.getSaleproductLists();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
});
},
//装箱操作
handlePack(scope) {
this.packData = Object.assign({}, scope.row);
this.dialogType = "new";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
gePack(scope.row.id).then((response) => {
if (response.data) {
this.packlist = response.data.detail;
}
});
this.saleproductId = scope.row.id;
},
submitPack() {
this.packData.detail = this.packlist;
console.log(this.packData);
subPack(this.saleproductId, this.packData).then((res) => {
if (res.code >= 200) {
this.getSaleproductLists();
this.dialogVisible = false;
this.$message.success("成功");
}
});
},
//未装箱备注
handleNotPack(scope) {
this.dialogVisibles = true;
this.saleProductid = scope.row.id;
},
submitnotPack() {
notPackremark(this.saleProductid, this.notpackData).then((res) => {
if (res.code >= 200) {
this.getSaleproductLists();
this.dialogVisible = false;
this.$message.success("成功");
}
});
},
},
//未装箱备注
handleNotPack(scope) {
this.dialogVisibles = true;
this.saleProductid = scope.row.id;
},
submitnotPack() {
notPackremark(this.saleProductid, this.notpackData).then((res) => {
if (res.code >= 200) {
this.getSaleproductLists();
this.dialogVisible = false;
this.$message.success("成功");
}
});
},
},
};
};
</script>

View File

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

View File

@ -119,7 +119,7 @@
</el-col>
</el-row>
<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>
</div>
</div>
@ -356,7 +356,7 @@
var g = new dagreD3.graphlib.Graph().setGraph({
rankdir: 'DL',
nodesep: 100,
edgesep: 10,//两条线之间的距离
edgesep: 50,//两条线之间的距离
ranksep: 50,//节点之间的距离
marginx: 160,
marginy: 20,

View File

@ -1,23 +1,26 @@
<template>
<div class="app-container">
<el-card>
<div style="margin-top: 2px">
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
>新增</el-button
>
</div>
<div style="margin-top: 2px">
<el-button
type="primary"
icon="el-icon-plus"
@click="handleCreate"
>
新增
</el-button>
</div>
</el-card>
<el-card style="margin-top: 2px">
<el-table
:data="wftransitionList"
style="width: 100%"
>
<el-table-column type="index" width="50" />
<el-table-column type="index" width="50"/>
<el-table-column width="180" label="名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column width="180" label="定时器(单位秒)">
<template slot-scope="scope">{{ scope.row.timer }}</template>
</el-table-column>
@ -31,32 +34,27 @@
<span v-if="scope.row.destination_state_">{{scope.row.destination_state_.name}}</span>
</template>
</el-table-column>
<el-table-column width="180" label="创建时间">
<el-table-column width="180" label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
width="220px"
>
<template slot-scope="scope">
<el-link @click="handleEdit(scope)">
编辑
</el-link>
<el-link
v-if="checkPermission(['wftransition_update'])"
@click="handleEdit(scope)"
>编辑</el-link
>
<el-link
v-if="checkPermission(['wftransition_delete'])"
type="danger"
@click="handleDelete(scope)"
>删除</el-link
>
删除
</el-link>
</template>
</el-table-column>
</el-table>
</el-card>
<el-dialog
:visible.sync="dialogVisible"
@ -70,13 +68,12 @@
:rules="rule1"
>
<el-form-item label="名称" prop="name">
<el-input v-model="wftransition.name" placeholder="名称" />
<el-input v-model="wftransition.name" placeholder="名称"/>
</el-form-item>
<el-form-item label="定时器(单位秒)" prop="timer">
<el-input v-model="wftransition.timer" type="number" placeholder="0" />
<el-form-item label="定时器(单位秒)" prop="timer">
<el-input v-model="wftransition.timer" type="number" placeholder="0"/>
</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-option
v-for="item in stateoptions"
@ -86,8 +83,8 @@
/>
</el-select>
</el-form-item>
<el-form-item label="目的状态" prop="destination_state">
<el-select v-model="wftransition.destination_state" placeholder="请选择" style="width:100%">
<el-form-item label="目的状态" prop="destination_state">
<el-select v-model="wftransition.destination_state" placeholder="请选择" style="width:100%">
<el-option
v-for="item in stateoptions"
:key="item.value"
@ -104,21 +101,19 @@
lang="zh"
/>
</el-form-item>
<el-form-item label="属性类型" prop="attribute_type">
<el-select style="width: 100%" v-model="wftransition.attribute_type" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
<el-form-item label="属性类型" prop="attribute_type">
<el-select style="width: 100%" v-model="wftransition.attribute_type" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="是否校验必填" prop="field_require_check">
<el-switch v-model="wftransition.field_require_check"></el-switch>
<el-form-item label="是否校验必填" prop="field_require_check">
<el-switch v-model="wftransition.field_require_check"></el-switch>
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
@ -128,28 +123,35 @@
</div>
</template>
<script>
import {getWfStateList, getWfTransitionList, createWfTransition,updateWfTransition,deleteWfTransition } from "@/api/workflow";
import checkPermission from "@/utils/permission";
import vueJsonEditor from 'vue-json-editor'
import { genTree } from "@/utils"
const defaultwftransition = {
name: "",
};
export default {
components: { vueJsonEditor },
name: "TST",
props: ["ID"],
data() {
return {
wftransition: defaultwftransition,
condition_expression:false,
/*wftransitionList: {
count:0
},*/
wftransitionList:[],
lable:'',
options_:[],
options: [{
import {
getWfStateList,
getWfTransitionList,
createWfTransition,
updateWfTransition,
deleteWfTransition
} from "@/api/workflow";
import checkPermission from "@/utils/permission";
import vueJsonEditor from 'vue-json-editor'
import {genTree} from "@/utils"
const defaultwftransition = {
name: "",
};
export default {
components: {vueJsonEditor},
name: "TST",
props: ["ID"],
data() {
return {
wftransition: defaultwftransition,
condition_expression: false,
/*wftransitionList: {
count:0
},*/
wftransitionList: [],
lable: '',
options_: [],
options: [{
value: 1,
label: '同意'
}, {
@ -159,109 +161,109 @@ export default {
value: 3,
label: '其他'
}],
stateoptions:[],
dialogVisible: false,
dialogType: "new",
rule1: {
name: [{ required: true, message: "请输入", trigger: "blur" }],
},
};
},
created() {
stateoptions: [],
dialogVisible: false,
dialogType: "new",
rule1: {
name: [{required: true, message: "请输入", trigger: "blur"}],
this.getWfStateList();
this.getList();
},
methods: {
checkPermission,
getList() {
getWfTransitionList(this.ID).then((response) => {
if (response.data) {
this.wftransitionList = response.data;
}
});
},
};
},
getWfStateList() {
getWfStateList(this.ID).then((response) => {
if (response.data) {
this.stateoptions = genTree(response.data);
}
});
created() {
this.getWfStateList();
this.getList();
},
handleCreate() {
this.wftransition = Object.assign({}, defaultwftransition);
this.dialogType = "new";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleEdit(scope) {
this.wftransition = Object.assign({}, scope.row); // copy obj
this.dialogType = "edit";
this.dialogVisible = true;
// this.wftransition.condition_expression = JSON.stringify(scope.row.condition_expression)
// this.$nextTick(() => {
// this.$refs["Form"].clearValidate();
// });
},
async confirm(form) {
this.$refs[form].validate((valid) => {
if (valid) {
const isEdit = this.dialogType === "edit";
if (isEdit) {
updateWfTransition(this.wftransition.id, this.wftransition).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
} else {
this.wftransition.workflow=this.ID;
createWfTransition(this.wftransition).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
methods: {
checkPermission,
getList() {
getWfTransitionList(this.ID).then((response) => {
if (response.data) {
this.wftransitionList = response.data;
}
} else {
return false;
}
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deleteWfTransition(scope.row.id);
this.getList();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
});
},
getWfStateList() {
getWfStateList(this.ID).then((response) => {
if (response.data) {
this.stateoptions = genTree(response.data);
}
});
},
handleCreate() {
this.wftransition = Object.assign({}, defaultwftransition);
this.dialogType = "new";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleEdit(scope) {
this.wftransition = Object.assign({}, scope.row); // copy obj
this.dialogType = "edit";
this.dialogVisible = true;
// this.wftransition.condition_expression = JSON.stringify(scope.row.condition_expression)
// this.$nextTick(() => {
// this.$refs["Form"].clearValidate();
// });
},
async confirm(form) {
this.$refs[form].validate((valid) => {
if (valid) {
const isEdit = this.dialogType === "edit";
if (isEdit) {
updateWfTransition(this.wftransition.id, this.wftransition).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
} else {
this.wftransition.workflow = this.ID;
createWfTransition(this.wftransition).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
}
} else {
return false;
}
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deleteWfTransition(scope.row.id);
this.getList();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
});
},
},
},
};
};
</script>

View File

@ -16,9 +16,10 @@
:data="subPlanList"
fit
style="width: 100%"
height="100"
stripe
border
height="100"
highlight-current-row
v-el-height-adaptive-table="{bottomOffset: 50}"
>
<el-table-column type="index" width="50"/>
@ -70,7 +71,7 @@
首件检验
</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"
@click="handleTestContinue(scope)"
>
@ -90,6 +91,13 @@
>
查看
</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>
</el-table-column>
</el-table>
@ -215,12 +223,19 @@
</div>
</el-row>
</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>
<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>
</template>
@ -231,6 +246,7 @@
import faceLogin from '@/components/faceLogin/review.vue';
import {getProcessList,getrecordformList} from "@/api/mtm";
import {getsubplanList} from "@/api/wpm";
import {getTestRecordExport} from "@/api/qm";
import {firstTestInit,firstAudit} from "@/api/pm";
import {getTestRecordItem,putTestRecordItem,subTestRecordItem} from "@/api/qm";
@ -256,6 +272,11 @@
enabled:true,
material:null
},
checkParams:{
id:null,
is_testok:true,
record_data:null,
},
planId:null,
leader:null,
recordId: null,
@ -272,6 +293,7 @@
reviewVisible:false,
recordVisible:false,
is_midtesting:false,
limitedUserCheck:false,
is_testok:false,
formName:'首件确认检查表',
update_time:'',
@ -296,6 +318,8 @@
changeIndex(item,index) {
this.activeIndex = index;
this.listQuery.process = item.id;
this.subPlanList = [];
this.count = 0;
this.getTableData();
},
@ -341,6 +365,7 @@
//首件审批
handleSelectclick(scope,index){
let that = this;
debugger;
this.reviewVisible = true;
that.planId = scope.row.id;
that.leader_1 = scope.row.leader_1_?scope.row.leader_1_.name:null;
@ -445,27 +470,56 @@
});
},
//提交首件检查
//提交首件检查:需要人脸识别进行身份验证
recordSubmit(value) {
let that = this;
let id = value.id;
let params = {};
params.record_data = value.record_data;
params.id = value.id;
params.is_testok = value.is_testok;
putTestRecordItem(id, params).then((res) => {
if (res.code >= 200) {
subTestRecordItem(id, params).then((res) => {
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) => {
if (res.code >= 200) {
that.recordVisible = false;
that.getTableData();
subTestRecordItem(id, params).then((res) => {
debugger;
that.limitedUserCheck = false;
if (res.code >= 200) {
that.recordVisible = false;
that.getTableData();
}else{
that.$message.error(res.msg)
}
}).catch(()=>{
that.limitedUserCheck = false;
});
} else {
that.$message.error(res.msg)
}
}).catch((err) => {
that.$message.error(err);
});
} else {
that.$message.error(res.msg)
}
}).catch((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() {
this.getProcessList();

View File

@ -61,6 +61,8 @@
>
<template slot-scope="scope">{{ scope.row.step_.name }}</template>
</el-table-column>
<el-table-column label="创建时间" prop="create_time">
</el-table-column>
<el-table-column align="center" label="操作" width="220px">
<template slot-scope="scope">
<el-link
@ -76,7 +78,6 @@
检验记录
</el-link>
<el-link
v-if="checkPermission(['wp_scrap'])"
type="danger"
@click="handleScrapbcp(scope)"
>
@ -176,6 +177,8 @@
>
<template slot-scope="scope">{{ scope.row.step_.name }}</template>
</el-table-column>
<el-table-column label="创建时间" prop="create_time">
</el-table-column>
<el-table-column align="center" label="操作" width="220px">
<template slot-scope="scope">
<el-link
@ -267,7 +270,12 @@
<template slot-scope="scope">{{ scope.row.step_.name }}</template>
</el-table-column>
<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 align="center" label="操作" width="220px">
<template slot-scope="scope">
@ -360,19 +368,24 @@
<template slot-scope="scope">{{ scope.row.subproduction_plan_.number }}</template>
</el-table-column>
<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 align="center" label="操作" width="220px">
<template slot-scope="scope">
<el-link
v-if="checkPermission(['wmaterial_scrap'])"
v-if="checkPermission(['wp_scrap'])"
type="danger"
@click="handleScrap(scope)"
>
报废
</el-link>
<el-link
v-if="checkPermission(['operation_hear'])&&!scope.row.ticket"
v-if="checkPermission(['operation_hear'])&&scope.row.ticket==null"
type="primary"
@click="handleRetrial(scope)"
>
@ -426,6 +439,8 @@
>
<template slot-scope="scope">{{ scope.row.step_.name }}</template>
</el-table-column>
<el-table-column label="创建时间" prop="create_time">
</el-table-column>
<el-table-column align="center" label="操作" width="220px">
<template slot-scope="scope">
<el-link
@ -471,7 +486,7 @@
</el-dialog>
<!--复检检验表单-->
<el-dialog
width="60%"
width="75%"
:title="formName"
@close="recordCancel"
:visible.sync="limitedReview"
@ -491,7 +506,7 @@
@recordCancel="recordCancel"
/>
</el-dialog>
<!--检查表显示-->
<!--复检检验表单-->
<el-dialog
width="60%"
:title="formName"
@ -505,6 +520,8 @@
:hasPicture="hasPicture"
:formID="recordform"
:wproduct="wproduct"
:remark="remark"
:numbers="numbers"
:recordId="recordId"
:isDisabled="isDisabled"
:isMidTesting="is_midtesting"
@ -584,7 +601,7 @@
查看
</el-link>
<el-link
v-if="checkPermission(['wp_test_init'])"
v-if="checkPermission(['testrecord_delete'])"
@click="delTestRecord(scope)"
>
删除
@ -732,13 +749,21 @@
</div>
</el-col>
<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>
<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>
</el-col>
<el-button @click="exportDom">导出</el-button>
</el-row>
</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>
</template>
<script>
@ -748,18 +773,23 @@
import checkPermission from "@/utils/permission";
import customForm from '@/components/customForm/index';
import reviewForm from '@/components/customForm/review';
import faceLogin from '@/components/faceLogin/review.vue';
import {createTicket, getWorkflowInit} from "@/api/workflow";
import {getrecordformList, getrffieldList} from "@/api/mtm";
import {getwproductList, wproductPutin, createputins, testInit, scrap, getRetrial} from "@/api/wpm";
import {getTestRecord, getTestRecordItem, putTestRecordItem, delTestRecordItem, subTestRecordItem} from "@/api/qm";
// import {genTree} from "@/utils";
import {getTestRecord, getTestRecordItem, putTestRecordItem, delTestRecordItem, subTestRecordItem,getTestRecordExport} from "@/api/qm";
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 = {};
export default {
inject: ['reload'],
components: {Pagination, customForm, reviewForm},
components: {Pagination, customForm, reviewForm, faceLogin},
data() {
return {
exportFormId:null,
testitem: defaultetestitem,
formbcp: {},
form: {remark: "", warehouse: ""},
@ -798,6 +828,11 @@
page: 1,
page_size: 20,
},
params: {
id: null,
is_testok: true,
record_data: null
},
activeName: "1",
create_by_: '',
update_time: '',
@ -874,6 +909,7 @@
mutipID: [],
wproduct: null,
isPost: false,
limitedPhoto: false,
is_midtesting: false,
isDisabled: false,
origin_test: null,
@ -901,7 +937,9 @@
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: '包边'}],
remark:'',
numbers:null,
};
},
computed: {},
@ -915,6 +953,20 @@
// this.getLists();
},
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,
handleClick(tab) {
this.listLoading = true;
@ -931,6 +983,7 @@
this.getList3();
}
},
//待检半成品列表
getList() {
this.listLoading = true;
@ -1178,6 +1231,8 @@
that.innerIndex = index;
// this.outerVisible = true;
that.wproduct = scope.row.id;//半成品ID
this.numbers = null;
this.remark = '';
that.listQueryrecordform.material = scope.row.material;
if (index === '3') {
that.listQueryrecordform.type = 40;
@ -1227,11 +1282,14 @@
//点击记录里的检验
handleInspectionRecord(scope) {
debugger;
let that = this;
that.fieldList = [];
that.recordVisible = false;
that.recordId = scope.row.id;
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;
if (that.innerIndex !== '2') {//非复检
getrffieldList({form: this.recordform, enabled: true, page: 1, page_size: 100}).then((response) => {
@ -1309,11 +1367,14 @@
that.fieldList = [];
that.create_by_ = scope.row.create_by_.name;
that.update_time = scope.row.update_time;
that.exportFormId = scope.row.id;
getTestRecordItem(scope.row.id).then((res) => {
if (res.code >= 200) {
that.recordFinishedVisible = true;
that.formName = res.data.form_.name;
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 = {};
params.record_data = value.record_data;
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) => {
if (res.code >= 200) {
that.recordVisible = false;
@ -1466,33 +1533,72 @@
});
},
//记录提交检查项目
//记录提交检查项目出现人脸验证弹窗
recordSubmit(value) {
let that = this;
let id = value.id;
let params = {};
params.record_data = value.record_data;
params.id = value.id;
params.is_testok = value.is_testok;
putTestRecordItem(id, params).then((res) => {
if (res.code >= 200) {
subTestRecordItem(id, params).then((res) => {
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) => {
if (res.code >= 200) {
that.recordVisible = false;
that.limitedReview = false;
that.limitedCheckRecord = false;
that.getList();
that.getList2();
that.getList1();
that.getList3();
that.refreshRecord();
subTestRecordItem(id, params).then((res) => {
if (res.code >= 200) {
that.recordVisible = false;
that.limitedReview = false;
that.limitedCheckRecord = false;
that.getList();
that.getList2();
that.getList1();
that.getList3();
that.refreshRecord();
} else {
that.$message.error(res.msg)
}
}).catch(() => {});
} else {
that.$message.error(res.msg)
}
}).catch((err) => {
that.$message.error(err);
});
} else {
this.$message.error(res.msg)
}
}).catch((err) => {
this.$message.error(err);
});
}).catch(() => {
that.limitedPhoto = false;
});
}
},
//第一次保存提交检查项目
@ -1504,6 +1610,19 @@
this.getList1();
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() {
getUserList({page: 0}).then(response => {

View File

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

View File

@ -10,7 +10,23 @@
>查看作业指导书
</el-button>
</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"
inline="true"
:model="operationData"
@ -22,6 +38,24 @@
disabled="disabled"
></el-input>
</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-input
v-model="operationData.user"
@ -35,16 +69,9 @@
></el-input>
</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>
<!--
&lt;!&ndash;
<el-form-item label="边角料">
<el-radio-group v-model="operationData.use_scrap">
<el-radio border
@ -58,7 +85,7 @@
<el-form-item label="备注" v-if="operationData.use_scrap">
<el-input type="textarea" v-model="operationData.remark"></el-input>
</el-form-item>
!-->
!&ndash;&gt;
<el-form-item v-if="operationData.use_scrap">
<el-button
type="primary"
@ -68,7 +95,7 @@
</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</el-form>-->
<el-drawer
title="作业指导书查看!"
:visible.sync="drawer"
@ -249,11 +276,16 @@
<el-table-column align="center" label="操作" width="100px">
<template slot-scope="scope">
<el-link
v-if="checkPermission(['warehouse_update'])"
type="primary"
@click="handlerecord(scope)"
>填写表单
</el-link>
<el-link
v-if="scope.row.is_filled"
type="primary"
@click="handlerecordExport(scope)"
>导出
</el-link>
</template>
</el-table-column>
</el-table>
@ -647,7 +679,6 @@
.word-wrap {
padding: 25px;
}
.box-card {
height: 300px;
}
@ -669,22 +700,20 @@
deleteOperationequip,
deleteOperationwproduct,
gettoolList,
createTool,
createInputs,
recordInit,
createOutputs,
deleteOperationeinput,
wproductPlace,
} from "@/api/wpm";
import mammoth from "mammoth";
import {getrffieldList, gettechdocList} from "@/api/mtm";
import { gettechdocList} from "@/api/mtm";
import checkPermission from "@/utils/permission";
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';
export default {
components: {Pagination, faceLogin},
components: {faceLogin},
inject: ["reload"],
data() {
return {
@ -811,9 +840,8 @@
pdf: "",
};
},
computed: {},
watch: {},
created() {
mounted() {
this.id = this.$route.params.id; //操作ID
this.readbook();
this.getList(); //边角料
@ -826,6 +854,7 @@
this.getprogressList(); //产出物料调出
this.gettoolList(); //工序工装
},
methods: {
checkPermission,
@ -890,6 +919,18 @@
getoperation(this.id).then((response) => {
if (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) {
this.operationData.user = response.data.create_by_.name;
} else {
@ -991,13 +1032,23 @@
this.formID = scope.row.id;
recordInit(this.formID).then((response) => {
if (response.data) {
debugger;
this.fieldList = response.data;
this.fieldList.name = response.data.form_.name;
}
});
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() {
@ -1208,9 +1259,10 @@
getMsgFormSon(data) {
let that = this;
that.operationData.user = data.name;
let text = '确定以操作员'+data.name+'身份提交?';
if (data.token !== '' && data.token !== null && data.token !== undefined) {
if (that.inputData == "") {
that.$confirm("没有消耗物料确定提交吗?", "提示", {
that.$confirm("没有消耗物料"+text, "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
@ -1229,16 +1281,26 @@
that.limitedPhoto = false;
});
} else {
submitOperation(that.id,{token:data.token}).then((res) => {
if (res.code === 200) {
that.$router.push({name: "operation"});
that.$message.success("操作提交成功!");
}else{
that.$message.error(res.msg)
}
}).catch((err) => {
that.$message.error(err);
this.$confirm(text, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
that.limitedPhoto = false;
submitOperation(that.id,{token:data.token}).then((res) => {
if (res.code === 200) {
that.$router.push({name: "operation"});
that.$message.success("操作提交成功!");
}else{
that.$message.error(res.msg)
}
}).catch((err) => {
that.$message.error(err);
});
}).catch(() => {
that.limitedPhoto = false;
});
}
}
},

View File

@ -9,8 +9,9 @@
border
fit
stripe
height="100"
highlight-current-row
max-height="600"
v-el-height-adaptive-table="{bottomOffset: 60}"
>
<el-table-column type="index" width="50"/>
<el-table-column label="成品名称">
@ -53,7 +54,6 @@
</el-table-column>
</el-table>
<pagination
v-show="wproductList.count > 0"
:total="wproductList.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.page_size"
@ -73,8 +73,9 @@
border
fit
stripe
height="100"
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="index" width="50"/>
@ -91,6 +92,12 @@
{{ actstate_[scope.row.act_state] }}
</template>
</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="指派订单">
<template slot-scope="scope" v-if="scope.row.order_">
{{scope.row.order_.number }}
@ -118,7 +125,6 @@
</el-table-column>
</el-table>
<pagination
v-show="wproductList1.count > 0"
:total="wproductList1.count"
:page.sync="listQuery1.page"
:limit.sync="listQuery1.page_size"
@ -282,16 +288,27 @@
<el-button type="primary" @click="putins"> </el-button>
</div>
</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>
</template>
<script>
// import {getOrderList} from "@/api/sam";
import checkPermission from "@/utils/permission";
import {getWarehouseList} from "@/api/inm";
import { getrecordformList, getrffieldList} from "@/api/mtm";
// import {genTree} from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
import customForm from "@/components/customForm/index";
import faceLogin from '@/components/faceLogin/review.vue';
import {
getwproductList,
wproductTest,
@ -309,12 +326,12 @@
const defaultetestitem = {};
export default {
components: {Pagination, customForm},
components: {Pagination, customForm,faceLogin},
data() {
return {
testitem: defaultetestitem,
form: {remark: "", warehouse: ""},
form1: {},
submitForm: {},
wproductList: {
count: 0,
},
@ -366,11 +383,13 @@
recordList: [],
recordformList: [],
recordform: null,
submitFormId: null,
fifo_detail: "",
listQueryrecordform: {
page: 0,
},
hasPicture: false,
limitedPhoto: false,
outerVisible: false,
innerVisible: false,
dialogFormVisible: false,
@ -674,12 +693,12 @@
//记录提交检查项目
recordSubmit(value) {
let that = this;
let id = value.id;
let params = {};
params.record_data = value.record_data;
params.is_testok = value.is_testok;
putTestRecordItem(id, params)
// let that = this;
this.submitFormId = value.id;
this.submitForm.record_data = value.record_data;
this.submitForm.is_testok = value.is_testok;
this.limitedPhoto = true;
/*putTestRecordItem(id, params)
.then((res) => {
if (res.code >= 200) {
subTestRecordItem(id, params).then((res) => {
@ -698,7 +717,7 @@
})
.catch((err) => {
this.$message.error(err);
});
});*/
},
//第一次保存提交检查项目
@ -706,6 +725,55 @@
this.outerVisible = 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>

View File

@ -1,238 +1,247 @@
<template>
<div class="app-container">
<el-tabs v-model="activeName" @tab-click="handleClick" type="border-card">
<el-tab-pane
v-for="item in processOption"
:key="item.name"
:label="item.name"
:name="item.id"
:closable="item.close"
>
<el-table
:data="subproductionplanList.results"
border
stripe
style="width: 100%"
height="250"
highlight-current-row
@current-change="handleCurrentChange"
<el-card>
<el-tabs v-model="activeName" @tab-click="handleClick" type="border-card">
<el-tab-pane
v-for="item in processOption"
:key="item.name"
:label="item.name"
:name="item.id"
:closable="item.close"
>
<el-table-column type="index" width="50"/>
<el-table-column label="子计划编号" prop="number" min-width="100" show-overflow-tooltip>
</el-table-column>
<el-table-column label="产品名称" min-width="120" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.plan_product_.name}}
</template>
</el-table-column>
<el-table-column label="产品型号">
<template slot-scope="scope">
{{scope.row.product_.specification}}
</template>
</el-table-column>
<el-table-column label="生产主产品" min-width="130" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.product_.name}}
</template>
</el-table-column>
<el-table-column label="名称" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.subproduction_.name}}
</template>
</el-table-column>
<el-table-column label="生产车间" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.workshop_.name}}
</template>
</el-table-column>
<el-table-column label="子工序" min-width="160">
<template slot-scope="scope" v-if="scope.row.steps">
<el-tag
v-for="item in scope.row.steps"
:key="item.number"
:label="item.name"
:value="item.number"
>
{{ item.name }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="开工时间" prop="start_date" width="100">
</el-table-column>
<el-table-column label="完工时间" prop="end_date" width="100">
</el-table-column>
<el-table-column label="状态">
<template slot-scope="scope">
{{ state_[scope.row.state] }}
</template>
</el-table-column>
<el-table-column label="领料状态" width="80">
<template slot-scope="scope">
<el-tag v-if="scope.row.is_picked == false">未领料</el-tag>
<el-tag v-else>已领料</el-tag>
</template>
</el-table-column>
<el-table-column label="计划/生产/合格">
<template slot-scope="scope">
{{ scope.row.count }}/{{ scope.row.count_real }}/{{scope.row.count_ok}}
</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
width="80px"
fixed="right"
<el-table
:data="subproductionplanList.results"
border
stripe
style="width: 100%"
:height="tableHeight"
highlight-current-row
@current-change="handleCurrentChange"
>
<template slot-scope="scope">
<el-link
v-if="checkPermission(['wmaterial_pick'])&&!scope.row.is_picked"
type="success"
@click="handleNeed(scope)"
>
领料
</el-link>
<el-link
v-if="checkPermission(['wmaterial_pick'])&&scope.row.is_picked"
type="success"
@click="handleNeed(scope)"
>
继续领料
</el-link>
<el-link
v-if="checkPermission(['wmaterial_pick'])"
type="primary"
@click="handlepick(scope)"
>
领半成品
</el-link>
</template>
</el-table-column>
</el-table>
<pagination
v-show="subproductionplanList.count > 0"
:total="subproductionplanList.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.page_size"
@pagination="subproductionplanList"
/>
<el-row :gutter="2">
<el-col :span="12">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>半成品</span>
</div>
<el-button
v-for="item in steps"
v-show="checkPermission(['wmaterial_operation'])"
:key="item.number"
type="primary"
style="margin-left: 2px"
:label="item.name"
:value="item.number"
@click="handlework(item)"
>
{{ item.name }}
</el-button>
<el-button
v-if="checkPermission(['wmaterial_scrap'])"
id="scrap"
type="primary"
style="float: right; display: none"
@click="handleScrapbcp()"
>
报废
</el-button>
<el-badge :value="count" class="item" style="float:right">
<el-button
type="primary"
@click="handleAll()"
<el-table-column type="index" width="50"/>
<el-table-column label="子计划编号" prop="number" min-width="100" show-overflow-tooltip>
</el-table-column>
<el-table-column label="产品名称" min-width="120" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.plan_product_.name}}
</template>
</el-table-column>
<el-table-column label="产品型号">
<template slot-scope="scope">
{{scope.row.product_.specification}}
</template>
</el-table-column>
<el-table-column label="生产主产品" min-width="130" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.product_.name}}
</template>
</el-table-column>
<el-table-column label="名称" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.subproduction_.name}}
</template>
</el-table-column>
<el-table-column label="生产车间" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.workshop_.name}}
</template>
</el-table-column>
<el-table-column label="子工序" min-width="160">
<template slot-scope="scope" v-if="scope.row.steps">
<el-tag
v-for="item in scope.row.steps"
:key="item.number"
:label="item.name"
:value="item.number"
>
显示全部
</el-button>
</el-badge>
<el-table
border
fit
stripe
style="width: 100%"
max-height="300"
:data="wproductData"
@selection-change="handleSelectionChange"
{{ item.name }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="开工时间" prop="start_date" width="100">
</el-table-column>
<el-table-column label="完工时间" prop="end_date" width="100">
</el-table-column>
<el-table-column label="状态">
<template slot-scope="scope">
{{ state_[scope.row.state] }}
</template>
</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">
<template slot-scope="scope">
<el-tag v-if="scope.row.is_picked == false">未领料</el-tag>
<el-tag v-else>已领料</el-tag>
</template>
</el-table-column>
<el-table-column label="计划/生产/合格">
<template slot-scope="scope">
{{ scope.row.count }}/{{ scope.row.count_real }}/{{scope.row.count_ok}}
</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
width="80px"
fixed="right"
>
<template slot-scope="scope">
<el-link
v-if="checkPermission(['wmaterial_pick'])&&!scope.row.is_picked&&scope.row.production_plan_.state!==70&&scope.row.production_plan_.state!==80"
type="success"
@click="handleNeed(scope)"
>
领料
</el-link>
<el-link
v-if="checkPermission(['wmaterial_pick'])&&scope.row.is_picked&&scope.row.production_plan_.state!==70&&scope.row.production_plan_.state!==80"
type="success"
@click="handleNeed(scope)"
>
继续领料
</el-link>
<el-link
v-if="checkPermission(['wmaterial_pick'])&&scope.row.production_plan_.state!==70&&scope.row.production_plan_.state!==80"
type="primary"
@click="handlepick(scope)"
>
领半成品
</el-link>
</template>
</el-table-column>
</el-table>
<pagination
v-show="subproductionplanList.count > 0"
:total="subproductionplanList.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.page_size"
@pagination="subproductionplanList"
/>
</el-tab-pane>
</el-tabs>
</el-card>
<el-card>
<el-row :gutter="2">
<el-col :span="12">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>半成品</span>
</div>
<el-button
v-for="item in steps"
v-show="checkPermission(['wmaterial_operation'])"
:key="item.number"
type="primary"
style="margin-left: 2px"
:label="item.name"
:value="item.number"
@click="handlework(item)"
>
{{ item.name }}
</el-button>
<el-button
v-show="checkPermission(['wp_scrap'])&&activeName==1"
id="scrap"
type="primary"
style="float: right;"
@click="handleScrapbcp()"
>
报废
</el-button>
<el-badge :value="count" class="item" style="float:right">
<el-button
type="primary"
@click="handleAll()"
>
<el-table-column type="selection" width="40"></el-table-column>
<el-table-column type="index" width="50"/>
<el-table-column label="子计划编号" width="100" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.number }}</template>>
<template slot-scope="scope">
{{scope.row.subproduction_plan_.number}}
</template>
</el-table-column>
<el-table-column label="玻璃编号" prop="number" width="100" show-overflow-tooltip>
</el-table-column>
<el-table-column label="玻璃状态" width="100" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.material_.name}}
</template>
</el-table-column>
<el-table-column label="所在子工序" width="100" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.step_.name}}
</template>
</el-table-column>
<el-table-column label="进行状态" width="100" show-overflow-tooltip>
<template slot-scope="scope">
{{actstate_[scope.row.act_state]}}
</template>
</el-table-column>
<el-table-column label="不合格标记" width="100">
<template slot-scope="scope">
{{ ng_sign_[scope.row.ng_sign] }}
</template>
</el-table-column>
<el-table-column label="更新时间" prop="update_time" width="160">
</el-table-column>
</el-table>
</el-card>
</el-col>
<el-col :span="12">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>车间物料</span>
</div>
<el-table
:data="wmaterialList"
border
fit
stripe
style="width: 100%"
max-height="300"
>
<el-table-column type="index" width="50"/>
<el-table-column label="子计划编号" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.subproduction_plan_.number }}
</template>
</el-table-column>
<el-table-column label="物料名称" min-width="130" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.material_.name}}
</template>
</el-table-column>
<el-table-column label="物料单位">
<template slot-scope="scope">
{{scope.row.material_.unit}}
</template>
</el-table-column>
<el-table-column prop="batch" label="物料批次">
</el-table-column>
<el-table-column prop="count" label="物料数量">
</el-table-column>
</el-table>
</el-card>
</el-col>
</el-row>
</el-tab-pane>
</el-tabs>
显示全部
</el-button>
</el-badge>
<el-table
border
fit
stripe
style="width: 100%"
:height="secondTableHeight"
:data="wproductData"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="40"></el-table-column>
<el-table-column type="index" width="50"/>
<el-table-column label="子计划编号" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.number }}</template>>
<template slot-scope="scope">
{{scope.row.subproduction_plan_.number}}
</template>
</el-table-column>
<el-table-column label="玻璃编号" prop="number" min-width="100" show-overflow-tooltip>
</el-table-column>
<el-table-column label="玻璃状态" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.material_.name}}
</template>
</el-table-column>
<el-table-column label="所在子工序" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.step_.name}}
</template>
</el-table-column>
<el-table-column label="进行状态" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
{{actstate_[scope.row.act_state]}}
</template>
</el-table-column>
<el-table-column label="不合格标记" min-width="100">
<template slot-scope="scope">
{{ ng_sign_[scope.row.ng_sign] }}
</template>
</el-table-column>
<el-table-column label="更新时间" prop="update_time" min-width="160">
</el-table-column>
</el-table>
</el-card>
</el-col>
<el-col :span="12">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>车间物料</span>
</div>
<el-table
:data="wmaterialList"
border
fit
stripe
style="width: 100%"
:height="tableHeight"
>
<el-table-column type="index" width="50"/>
<el-table-column label="子计划编号" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.subproduction_plan_.number }}
</template>
</el-table-column>
<el-table-column label="物料名称" min-width="130" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.material_.name}}
</template>
</el-table-column>
<el-table-column label="物料单位">
<template slot-scope="scope">
{{scope.row.material_.unit}}
</template>
</el-table-column>
<el-table-column prop="batch" label="物料批次">
</el-table-column>
<el-table-column prop="count" label="物料数量">
</el-table-column>
</el-table>
</el-card>
</el-col>
</el-row>
</el-card>
<el-dialog
title="半成品报废"
:close-on-click-modal="false"
@ -774,14 +783,16 @@
},
state_: {
0: "制定中",
1: "已下达",
2: "已接受",
3: "生产中",
4: "已完成",
10: "制定中",
20: "已下达",
30: "已接受",
40: "生产中",
50: "已完成",
60: "军检完成",
70: "暂停",
80: "终止",
},
listLoading: true,
listLoading: true,
id: "",
dialogTableVisible: false,
dialogVisible: false,
@ -828,6 +839,8 @@
{lable: "其他", value: 40},
],
count: null,
tableHeight: null,
secondTableHeight: null,
};
},
process: "",
@ -841,29 +854,25 @@
//选项卡切换
handleClick(tab) {
this.process = tab.name;
this.listQuery.process = tab.name;
if (tab.name == 1) {
document.getElementById("scrap").style.display = "block";
}
this.steps = [];
getsubplanList(this.listQuery).then((response) => {
let that = this;
that.process = tab.name;
that.listQuery.process = tab.name;
that.steps = [];
getsubplanList(that.listQuery).then((response) => {
if (response.data) {
this.subproductionplanList = response.data;
that.subproductionplanList = response.data;
}
});
//子工序列表
getStepLists(tab.name).then((response) => {
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) {
// this.steps = row.steps; //调出子工序
this.subproduction_plan = row.id; //子计划Id
this.getwproductLists();
getwmaterialList({
@ -915,9 +923,29 @@
},
//大工序工序渲染
getProcessList() {
let that = this;
getProcessList({page: 0}).then((response) => {
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) => {
if (res.code >= 200) {
this.dialogVisiblenw = false;
this.$message.success("领料成功!");
this.listQuery.process = this.process;
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>

View File

@ -25,12 +25,14 @@ class CleanDataView(APIView):
"""
Order.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)
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()
Ticket.objects.all().delete(soft=False)
Operation.objects.all().delete()
from apps.pum.models import PuOrder
PuOrder.objects.all().delete(soft=False)
return Response()

View File

@ -20,10 +20,15 @@ class EmployeeNotWorkRemarkSerializer(ModelSerializer):
fields = ['not_work_remark']
class FaceLoginSerializer(serializers.Serializer):
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):
base64 = serializers.CharField()
tolerance = serializers.FloatField(required=False, default=0.36)
class ClockRecordListSerializer(serializers.ModelSerializer):
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)

View File

@ -10,7 +10,40 @@ from django.core.cache import cache
class HRMService:
@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())
filepath = settings.BASE_DIR +'/temp/' + filename +'.png'
with open(filepath, 'wb') as f:
@ -30,13 +63,34 @@ class HRMService:
face_datas = cache.get('face_datas')
face_users = cache.get('face_users')
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):
if value:
# 识别成功
user = User.objects.get(id=face_users[index])
return user, ''
return None, '人脸未匹配,请调整位置'
true_num = true_num + 1
user_index.append(index)
return user_index
@classmethod
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,
user__is_active=True).values('user', 'face_data')
user__is_active=True, user__is_deleted = False).values('user', 'face_data')
face_users = []
face_datas = []
for i in facedata_queyset:

View File

@ -1,6 +1,6 @@
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 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')
urlpatterns = [
path('facelogin/', FaceLogin.as_view()),
path('facelogin_path/', FacePathLogin.as_view()),
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.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
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):
now = timezone.now()
now_local = timezone.localtime()
if 8<=now_local.hour<=17:
if 6<=now_local.hour<=17:
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:
ins, created = ClockRecord.objects.get_or_create(
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,
@ -120,9 +120,9 @@ class ClockRecordViewSet(CreateModelMixin, ListModelMixin, GenericViewSet):
'create_by':user,
'create_time':now
})
if not created:
ins.update_time = now
ins.save()
# if not created:
# ins.update_time = now
# ins.save()
# 设为在岗
Employee.objects.filter(user=user).update(is_atwork=True, last_check_time=now)
return Response(UserSimpleSerializer(instance=user).data)
@ -160,7 +160,45 @@ class FaceLogin(CreateAPIView):
人脸识别登录
"""
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:
refresh = RefreshToken.for_user(user)
# 可设为在岗

View File

@ -82,8 +82,7 @@ class FIFOItemViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, Updat
"""
出入库记录详情表
"""
perms_map = {'get': '*', 'post':'fifoitem_create',
'put':'fifoitem_update', 'delete':'fifoitem_delete'}
perms_map = {'*':'*'}
queryset = FIFOItem.objects.select_related('material', 'fifo').prefetch_related('files').all()
serializer_class = FIFOItemSerializer
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)
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)
type = models.PositiveSmallIntegerField('物料类型', choices= type_choices, default=1)
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_safe = models.PositiveIntegerField('安全库存总数', 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:
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)
enabled = models.BooleanField('是否启用', default=False)
number = models.CharField('编号', null=True, blank=True, max_length=32)
export_template = models.CharField('导出模板', max_length=200, null=True, blank=True)
class Meta:
verbose_name = '记录表格'
@ -212,7 +215,7 @@ class RecordFormField(CommonAModel):
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)
span = models.PositiveSmallIntegerField('span值', default=12)
class Meta:
verbose_name = '记录表格字段'
@ -263,6 +266,7 @@ class UsedStep(CommonADModel):
"""
step = models.ForeignKey(Step, verbose_name='子工序', on_delete=models.CASCADE, related_name='usedstep')
need_test = models.BooleanField('工序内检验', default=False)
reuse_form = models.BooleanField('复用上表', default=True)
remark = models.TextField('生产备注', null=True, blank=True)
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):
file_ = FileSimpleSerializer(source='file', read_only=True)
class Meta:
model = Material
fields = '__all__'
class MaterialDetailSerializer(serializers.ModelSerializer):
processes_ = serializers.SerializerMethodField()
file_ = FileSimpleSerializer(source='file', read_only=True)
class Meta:
model = Material
fields = '__all__'
@ -44,7 +46,7 @@ class PackItemUpdateSerializer(serializers.ModelSerializer):
class MaterialSimpleSerializer(serializers.ModelSerializer):
class Meta:
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):
material_ = MaterialSimpleSerializer(source='material', read_only=True)
@ -161,7 +163,7 @@ class UsedStepCreateSerializer(serializers.ModelSerializer):
"""
class Meta:
model = UsedStep
fields = ['step', 'subproduction', 'remark', 'need_test']
fields = ['step', 'subproduction', 'remark', 'need_test', 'reuse_form']
class UsedStepUpdateSerializer(serializers.ModelSerializer):
"""
@ -169,7 +171,7 @@ class UsedStepUpdateSerializer(serializers.ModelSerializer):
"""
class Meta:
model = UsedStep
fields = ['remark', 'need_test']
fields = ['remark', 'need_test', 'reuse_form']
class UsedStepListSerializer(serializers.ModelSerializer):
"""
@ -209,10 +211,10 @@ class RecordFormSerializer(serializers.ModelSerializer):
class RecordFormCreateSerializer(serializers.ModelSerializer):
form = serializers.PrimaryKeyRelatedField(
queryset=RecordForm.objects.all(), label="复制表ID", required=False)
queryset=RecordForm.objects.all(), label="复制表ID", required=False, write_only=True)
class Meta:
model = RecordForm
fields = ['name', 'type', 'step', 'material', 'number', 'enabled', 'form']
fields = ['name', 'type', 'step', 'material', 'number', 'enabled', 'form', 'export_template']
# def validate(self, attrs):
@ -225,7 +227,7 @@ class RecordFormCreateSerializer(serializers.ModelSerializer):
class RecordFormUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = RecordForm
fields = ['name', 'type', 'number', 'enabled']
fields = ['name', 'type', 'number', 'enabled', 'export_template', 'material']
# def validate(self, attrs):
# if attrs['enabled']:
@ -278,7 +280,7 @@ class RecordFormFieldCreateSerializer(serializers.ModelSerializer):
class RecordFormFieldUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = RecordFormField
exclude = ['field_key']
fields = '__all__'
class RecordFormFieldSimpleSerializer(serializers.ModelSerializer):
class Meta:

View File

@ -19,7 +19,7 @@ class MaterialViewSet(PageOrNot, CreateUpdateModelAMixin, ModelViewSet):
"""
perms_map = {'get': '*', 'post': 'material_create',
'put': 'material_update', 'delete': 'material_delete'}
queryset = Material.objects.all()
queryset = Material.objects.select_related('file').all()
serializer_class = MaterialSerializer
search_fields = ['name', 'number']
filterset_class = MaterialFilterSet
@ -35,8 +35,8 @@ class PackItemViewSet(CreateUpdateModelAMixin, ModelViewSet):
"""
装箱项目-增删改查
"""
perms_map = {'get': '*', 'post': 'packitem_create',
'put': 'packitem_update', 'delete': 'packitem_delete'}
perms_map = {'get': '*', 'post': 'material_update',
'put': 'material_update', 'delete': 'material_update'}
queryset = PackItem.objects.all()
serializer_class = PackItemSerializer
search_fields = ['name', 'number']
@ -64,7 +64,7 @@ class ProcessViewSet(PageOrNot, CreateUpdateModelAMixin, ModelViewSet):
ordering_fields = ['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):
"""
工序下的子工序
@ -166,7 +166,7 @@ class UsedStepViewSet(OptimizationMixin, CreateModelMixin, DestroyModelMixin, Li
'put':'subproduction_update', 'delete':'subproduction_update'}
queryset = UsedStep.objects.all()
filterset_fields = ['subproduction', 'step']
ordering = ['step__sort', '-step__create_time']
ordering = ['step__number', 'step__create_time']
def get_serializer_class(self):
if self.action =='create':
@ -179,12 +179,12 @@ class RecordFormViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet
"""
记录表格增删改查
"""
perms_map = {'get':'*', 'post':'recordform_create',
'put':'recordform_update', 'delete':'recordform_delete'}
perms_map = {'get':'*', 'post':'*',
'put':'*', 'delete':'*'}
queryset = RecordForm.objects.all()
filterset_fields = ['step', 'type', 'material', 'number', 'enabled']
search_fields = ['name']
ordering='id'
ordering=['id']
def get_serializer_class(self):
@ -216,10 +216,10 @@ class RecordFormViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet
instance.save()
if form:
for i in RecordFormField.objects.filter(form=form, is_deleted=False):
i.pk = None
i.form = instance
i.parent = None
i.save()
i.pk = None
i.form = instance
i.parent = None
i.save()
return Response()
@ -229,13 +229,13 @@ class RecordFormFieldViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelVi
"""
表格字段表 增删改查
"""
perms_map = {'get':'*', 'post':'recordform_update',
'put':'recordform_update', 'delete':'recordform_update'}
perms_map = {'get':'*', 'post':'*',
'put':'*', 'delete':'*'}
queryset = RecordFormField.objects.all()
filterset_fields = ['field_type', 'form']
search_fields = ['field_name', 'field_key']
ordering = 'sort'
ordering_fields = ['sort', 'id']
ordering = ['sort', 'create_time']
ordering_fields = ['sort', 'create_time']
def get_serializer_class(self):
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 rest_framework import serializers
from apps.qm.models import TestRecord
from apps.qm.serializers import TestRecordShortSerializer
from apps.sam.serializers import OrderSerializer, OrderSimpleSerializer
from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer, RecordFormSimpleSerializer, SubProductionSimpleSerializer
from apps.system.serializers import OrganizationSimpleSerializer, UserSimpleSerializer
@ -12,7 +11,7 @@ from utils.mixins import DynamicFieldsSerializerMixin
class ProductionPlanCreateFromOrderSerializer(serializers.ModelSerializer):
class Meta:
model = ProductionPlan
fields = ['order', 'count', 'start_date', 'end_date']
fields = ['order', 'count', 'start_date', 'end_date', 'number']
class ProductionPlanSerializer(DynamicFieldsSerializerMixin, serializers.ModelSerializer):
order_ = OrderSimpleSerializer(source='order', read_only=True)
@ -21,6 +20,11 @@ class ProductionPlanSerializer(DynamicFieldsSerializerMixin, serializers.ModelSe
model = ProductionPlan
fields ='__all__'
class ProductionPlanSimpleSerializer(serializers.ModelSerializer):
class Meta:
model = ProductionPlan
fields = ['number', 'state']
class ResourceCalSerializer(serializers.Serializer):
id = serializers.IntegerField(label='产品ID')
count = serializers.IntegerField(label='生产数量')
@ -37,6 +41,7 @@ class ResourceCalListSerializer(serializers.ListSerializer):
class SubProductionPlanListSerializer(DynamicFieldsSerializerMixin, serializers.ModelSerializer):
workshop_ = OrganizationSimpleSerializer(source='workshop', read_only=True)
production_plan_ = ProductionPlanSimpleSerializer(source='production_plan', read_only=True)
process_ = ProcessSimpleSerializer(source='process', read_only=True)
subproduction_ = SubProductionSimpleSerializer(source='subproduction', read_only=True)
product_ = MaterialSimpleSerializer(source='product', read_only=True)
@ -44,19 +49,20 @@ class SubProductionPlanListSerializer(DynamicFieldsSerializerMixin, serializers.
leader_1_ = UserSimpleSerializer(source='leader_1', read_only=True)
leader_2_ = UserSimpleSerializer(source='leader_2', 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:
model=SubProductionPlan
fields = '__all__'
def get_plan_product_(self, obj):
return MaterialSimpleSerializer(instance=obj.production_plan.product).data
def get_first_test_(self, obj):
tr = obj.first_test
if obj.first_test:
return {'id':tr.id, 'is_submited':tr.is_submited}
return None
# def get_first_test_(self, obj):
# if obj.first_test:
# return TestRecordShortSerializer(instance=obj.first_test).data
# return None
class SubProductionPlanUpdateSerializer(serializers.ModelSerializer):

View File

@ -71,7 +71,7 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel
pass
else:
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)
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',
'workshop', 'subproduction', 'product',
'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)
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
def issue(self, request, pk=None):
"""
@ -193,7 +193,7 @@ class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateMo
return Response()
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):
"""
开始生产

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_midtesting = models.BooleanField('是否子工序检验中', default=False)
remark = models.TextField('备注', default='')
number = models.CharField('玻璃编号', max_length=20, null=True, blank=True)
class TestRecordItem(CommonADModel):

View File

@ -1,7 +1,8 @@
from rest_framework import serializers
from apps.mtm.models import RecordForm, RecordFormField
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 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 = serializers.SerializerMethodField()
origin_test_ = TestRecordDetailBaseSerializer(source='origin_test', read_only=True)
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
update_by_ = UserSimpleSerializer(source='update_by', read_only=True)
create_by_ = UserStandardSerializer(source='create_by', read_only=True)
update_by_ = UserStandardSerializer(source='update_by', read_only=True)
wproduct_ = WProductBaseSerializer(source='wproduct', read_only=True)
class Meta:
model = TestRecord
fields = '__all__'
@ -127,7 +129,7 @@ class TestRecordUpdateSerializer(serializers.ModelSerializer):
record_data = TestRecordItemUpdatexSerializer(many=True, write_only=True)
class Meta:
model = TestRecord
fields = ['is_testok', 'record_data']
fields = ['is_testok', 'record_data', 'number', 'remark']
def update(self, instance, validated_data):
# 获取更新人

View File

@ -1,5 +1,7 @@
from rest_framework import exceptions, serializers
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.models import Standard, TestItem, TestRecord, TestRecordItem
from django.shortcuts import render
@ -13,6 +15,7 @@ from rest_framework.decorators import action
from apps.wpm.models import WProduct
from apps.wpm.services import WpmService
from rest_framework.exceptions import ParseError
# Create your views here.
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))))
with transaction.atomic():
obj.is_submited=True
obj.update_by = request.user
obj.save()
if obj.wproduct:
WpmService.update_wproduct_by_test(obj, request.user) # 这里已经做了日志记录和进度计算
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):
# serializer = self.get_serializer(data=request.data)
# serializer.is_valid(raise_exception=True)

View File

@ -43,10 +43,10 @@ class ContractCreateUpdateSerializer(serializers.ModelSerializer):
class OrderCreateUpdateSerializer(serializers.ModelSerializer):
class Meta:
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):
validated_data['number'] = 'DD' + ranstr(7)
# validated_data['number'] = 'DD' + ranstr(7)
return super().create(validated_data)
class OrderSerializer(DynamicFieldsSerializerMixin, serializers.ModelSerializer):

View File

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

View File

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

View File

@ -52,7 +52,7 @@ class PTaskSerializer(serializers.ModelSerializer):
class FileSimpleSerializer(serializers.ModelSerializer):
class Meta:
model =File
model = File
fields = ['id', 'name', 'file', 'path']
class FileSerializer(serializers.ModelSerializer):
@ -126,6 +126,16 @@ class UserSimpleSerializer(serializers.ModelSerializer):
model = User
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):
# dept_name = serializers.StringRelatedField(source='dept')
# 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()
@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):
"""

View File

@ -8,11 +8,11 @@ from apps.inm.serializers import WareHouseSimpleSerializer
from apps.inm.services import InmService
from apps.mtm.models import Material, RecordForm, RecordFormField, Step, SubprodctionMaterial
from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer, RecordFormSimpleSerializer, StepSimpleSerializer
from apps.pm.models import SubProductionPlan, SubProductionProgress
from django.db.models.aggregates import Sum, Count
from apps.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress
from django.utils import timezone
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.sam.serializers import OrderSimpleSerializer
from apps.system.models import User
@ -168,6 +168,8 @@ class WProductListSerializer(DynamicFieldsSerializerMixin, serializers.ModelSeri
children = serializers.SerializerMethodField()
to_order_ = OrderSimpleSerializer(source='to_order', read_only=True)
order_ = serializers.SerializerMethodField()
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
update_by_ = UserSimpleSerializer(source='update_by', read_only=True)
class Meta:
model = WProduct
fields = '__all__'
@ -242,6 +244,8 @@ class WProductDetailSerializer(serializers.ModelSerializer):
children = serializers.SerializerMethodField()
to_order_ = OrderSimpleSerializer(source='to_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:
model = WProduct
fields = '__all__'
@ -254,18 +258,22 @@ class WProductDetailSerializer(serializers.ModelSerializer):
class OperationDetailSerializer(serializers.ModelSerializer):
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)
class Meta:
model = Operation
fields = '__all__'
class OperationListSerializer(serializers.ModelSerializer):
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)
out_detail = serializers.SerializerMethodField()
# wproduct_ = serializers.SerializerMethodField()
count_work = serializers.SerializerMethodField()
equip_ = serializers.SerializerMethodField()
record_ = serializers.SerializerMethodField()
# count_work = serializers.SerializerMethodField()
# equip_ = serializers.SerializerMethodField()
# record_ = serializers.SerializerMethodField()
class Meta:
model = Operation
fields = '__all__'
@ -273,8 +281,31 @@ class OperationListSerializer(serializers.ModelSerializer):
# def get_wproduct_(self, obj):
# 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):
from django.db.models.aggregates import Sum
count_work = 0
if obj.step.type == Step.STEP_TYPE_NOM:
count_work = OperationWproduct.objects.filter(operation=obj).count()

View File

@ -2,28 +2,54 @@ from django.utils import timezone
from typing import List
from django.db.models.expressions import F
from apps.mtm.serializers import UsedStepListSerializer
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.system.models import User
from apps.wf.models import State, TicketFlow, Transition
from apps.wpm.models import Operation, OperationMaterial, WProduct, WproductFlow, WprouctTicket
from utils.tools import ranstr
from rest_framework.exceptions import ParseError
class WpmService(object):
@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
stepIds = [i['id'] for i in steps_list]
pindex = stepIds.index(nowstep.id)
need_test = steps_list[pindex].get('need_test', False)
if pindex + 1 < len(stepIds):
return Step.objects.get(pk=stepIds[pindex+1]), need_test
else:
return nowstep, need_test
used_steps = UsedStep.objects.filter(subproduction=subproduction_plan.subproduction).order_by('step__number')
if nowstep is None:
try:
nowstep = used_steps[0].step
except:
pass
for index, i in enumerate(used_steps):
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
def get_subplans_queryset_from_wproducts(cls, wproducts:List):
@ -49,7 +75,6 @@ class WpmService(object):
"""
is_testok = test.is_testok
wproduct = test.wproduct
test_i = None
if is_testok:
if wproduct.act_state == WProduct.WPR_ACT_STATE_TORETEST: # 复检
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 \
test.is_midtesting is True:
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: # 成品检验
wproduct.act_state = WProduct.WPR_ACT_STATE_TOFINALTEST
@ -70,7 +94,10 @@ class WpmService(object):
else:
wproduct.act_state = WProduct.WPR_ACT_STATE_OK
if wproduct.number is None: # 产生半成品编号
wproduct.number = 'WP'+ranstr(7)
if test.number:
wproduct.number = test.number
else:
raise ParseError('请提供玻璃编号')
# 去除ng_sign
if wproduct.ng_sign:
@ -108,7 +135,7 @@ class WpmService(object):
wproduct.update_by = user
wproduct.update_time = timezone.now()
wproduct.test = test_i
wproduct.test = None
wproduct.last_test_result = is_testok
wproduct.save()
# 添加日志

View File

@ -4,14 +4,14 @@ from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, \
from rest_framework.viewsets import GenericViewSet
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct
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.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress
from apps.pm.serializers import SubProductionPlanListSerializer, SubProductionProgressSerializer
from apps.qm.models import TestRecord, TestRecordItem
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 apps.wf.models import Workflow
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 rest_framework import status
from django.db.models import Count, Q
from rest_framework.exceptions import ParseError
from utils.tools import ranstr
@ -49,11 +49,7 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
"""
perms_map = {'get': '*'}
queryset = SubProductionPlan.objects.select_related(
'process', 'workshop', 'subproduction', 'product').filter(
production_plan__state__in =[
ProductionPlan.PLAN_STATE_WORKING, ProductionPlan.PLAN_STATE_ASSGINED
]
)
'process', 'workshop', 'subproduction', 'product', 'production_plan').exclude(state=SubProductionPlan.SUBPLAN_STATE_PLANING)
search_fields = []
serializer_class = SubProductionPlanListSerializer
filterset_fields = ['production_plan',
@ -160,7 +156,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
perms_map = {'get': '*'}
queryset = WProduct.objects.select_related('step', 'material',
'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
filterset_class = WProductFilterSet
search_fields = ['number', 'material__name', 'subproduction_plan__number']
@ -189,14 +185,14 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
vdata = serializer.validated_data
wproduct = vdata['wproduct']
form = vdata['form']
if wproduct.test:
raise exceptions.APIException('存在进行中检验')
# 根据情况创建一条检验记录
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_TOCOMBTEST]:
raise exceptions.APIException('该产品当前状态不可检验')
if wproduct.test:
raise exceptions.APIException('存在进行中检验')
savedict = dict(
create_by=request.user,
wproduct=wproduct,
@ -206,7 +202,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
step=wproduct.step,
form=form)
if wproduct.act_state == WProduct.WPR_ACT_STATE_TORETEST:
# 查找最近一条检验记录
# 查找最近一条工序检验记录
trs = wproduct.last_process_test
savedict['origin_test'] = trs
if not trs:
@ -216,9 +212,11 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
savedict['type'] = TestRecord.TEST_FINAL
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOCOMBTEST:
savedict['type'] = TestRecord.TEST_COMB
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and\
wproduct.step != wproduct.pre_step: # 如果是工序内检验
savedict['is_midtesting'] = True
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST:
_, 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
# if UsedStep.objects.filter(subproduction=wproduct.subproduction_plan.subproduction).first().need_test:
tr = TestRecord.objects.create(**savedict)
# 更新wproduct
wproduct.test = tr
@ -439,7 +437,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
WpmService.add_wproduct_flow_log(instance=obj, change_str=change_str)
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):
"""
流程卡
@ -530,19 +528,16 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
"""
perms_map = {'get': '*', 'post':'operation_create',
'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()
serializer_class = OperationListSerializer
filterset_fields = ['step', 'step__process', 'is_submited']
ordering_fields = ['id']
ordering = ['-id']
def get_queryset(self):
return self.queryset.filter(create_by=self.request.user)
def get_serializer_class(self):
if self.action == 'retrieve':
return OperationDetailSerializer
return OperationListSerializer
elif self.action == 'create':
return OperationCreateSerializer
elif self.action == 'update':
@ -608,6 +603,11 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
# 查询需要填写的自定义表格
forms = RecordForm.objects.filter(
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:
opr = OperationRecord()
opr.operation = op
@ -637,7 +637,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
opm.material = i.material
opm.type = SubprodctionMaterial.SUB_MA_TYPE_TOOL
opm.save()
return Response()
return Response(OperationListSerializer(instance=op).data)
@action(methods=['post'], detail=True, perms_map={'post': 'operation_submit'}, serializer_class=serializers.Serializer)
@transaction.atomic
@ -700,24 +700,32 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
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.pre_step = step
wp.material = wsp.product
if step == newstep:
wp.act_state = WProduct.WPR_ACT_STATE_TOTEST
if wp.test:# 如果有正在进行的工序中检验
wp.test.is_midtesting = False
wp.test.is_submited = False
wp.test.save()
last_test = wp.last_wp_test
if last_test and reuseForm:
last_test.is_midtesting = False
last_test.is_submited = False
last_test.save()
wp.test = last_test
wp.save()
else:
wp.act_state = WProduct.WPR_ACT_STATE_DOWAIT
if needTest:
if needTest: #子工序若需要检验
print(needTest, reuseForm)
wp.act_state = WProduct.WPR_ACT_STATE_TOTEST
if wp.test:# 如果有正在进行的工序中检验
wp.test.is_submited = False
wp.test.save()
last_test = wp.last_wp_test
if last_test and reuseForm:
last_test.is_midtesting = True
last_test.is_submited = False
last_test.save()
wp.test = last_test
wp.save()
wp.operation = None
wp.update_by = request.user
@ -734,7 +742,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
raise exceptions.APIException('请选择物料产出')
for i in omos:
if i.subproduction_progress.is_main:
newstep, _ = WpmService.get_next_step(
newstep, _, _ = WpmService.get_step_info(
i.subproduction_plan, step)
wpr = dict(material=i.material, step=newstep,
act_state=WProduct.WPR_ACT_STATE_DOWAIT, remark='',
@ -755,7 +763,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
if oms_w.count!=1:
raise exceptions.APIException('产出数量应为1')
# 校验单片数量是否正确, 暂时未写
newstep, needTest = WpmService.get_next_step(
newstep, needTest, reuseForm = WpmService.get_step_info(
oms_w.subproduction_plan, step)
wproduct = WProduct()
wproduct.material = oms_w.material
@ -763,14 +771,24 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
wproduct.subproduction_plan = oms_w.subproduction_plan
if step == newstep:
wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST
if wproduct.test:# 如果有正在进行的工序中检验
wproduct.test.is_midtesting = False
wproduct.test.is_submited = False
wproduct.test.save()
last_test = wproduct.last_wp_test
if last_test and reuseForm:
last_test.is_midtesting = False
last_test.is_submited = False
last_test.save()
wproduct.test = last_test
wproduct.save()
else:
wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
if needTest:
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(
@ -787,6 +805,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
else:
raise exceptions.APIException('产出物料未填写或填写错误')
op.is_submited = True
op.update_by = request.user
op.save()
# 如果是冷加工
@ -800,7 +819,7 @@ class OperationWproductViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMix
操作使用的半成品
"""
perms_map = {'get': '*', 'post':'operation_update',
'put':'operation_update', 'delete':'operation_delete'}
'put':'operation_update', 'delete':'operation_update'}
queryset = OperationWproduct.objects.select_related(
'subproduction_plan', 'material').all()
serializer_class = OperationWproductListSerializer
@ -831,7 +850,7 @@ class OperationEquipViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin,
操作使用的设备
"""
perms_map = {'get': '*', 'post':'operation_update',
'put':'operation_update', 'delete':'operation_delete'}
'put':'operation_update', 'delete':'operation_update'}
queryset = OperationEquip.objects.select_related(
'operation', 'equip').all()
serializer_class = OperationEquipListSerializer
@ -864,7 +883,7 @@ class OperationRecordViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin
操作使用的自定义表格
"""
perms_map = {'get': '*', 'post':'operation_update',
'put':'operation_update', 'delete':'operation_delete'}
'put':'operation_update', 'delete':'operation_update'}
queryset = OperationRecord.objects.select_related(
'operation', 'form').all()
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(
'operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_IN)
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(
'operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
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(
'operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_TOOL)
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