Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop

This commit is contained in:
shilixia 2022-02-21 13:51:00 +08:00
commit f552f995ab
18 changed files with 664 additions and 274 deletions

View File

@ -9,7 +9,7 @@
<el-row> <el-row>
<el-col <el-col
v-for="(item, $index) in formData" v-for="(item, $index) in formData"
v-show="filterBlock(item.parent,item.display_expression,$index,item.field_key)" v-show="filterBlock(item.display_expression,$index,item.field_key)"
:key="$index" :key="$index"
:span="12" :span="12"
style="position: relative" style="position: relative"
@ -281,79 +281,71 @@
} }
}, },
methods:{ methods:{
filterBlock(parent,rule,index,field_key){ filterBlock(rule,index,field_key){
let that = this; let that = this;
if(parent!==''&&parent!==null&&parent!==undefined){ if(rule!==''&&rule!==null&&rule!==undefined){
if(rule!==''&&rule!==null&&rule!==undefined){ let reg = /\{(.+?)\}/g;
let reg = /\{(.+?)\}/g; if(rule.indexOf('||')>-1||rule.indexOf('&&')>-1){
//let str = rule.replace(temp,'').replace('$','');//=='' let tam = '', arr = [];
//let y = that.checkForm[key]; if(rule.indexOf('||')>-1){
if(rule.indexOf('||')>-1||rule.indexOf('&&')>-1){ arr = rule.split('||');
let tam = '', arr = []; }else{
if(rule.indexOf('||')>-1){ arr = rule.split('&&');
arr = rule.split('||'); }
}else{ for (let i = 0;i<arr.length;i++){
arr = rule.split('&&'); //获取判断依据
} let a = '';
for (let i = 0;i<arr.length;i++){ a = arr[i].replace(/`/g,'');
//获取判断依据 a = '`'+ a+'`';
let a = ''; let tem =a.match(reg)[0];
a = arr[i].replace(/`/g,''); let ky = tem.replace(/\{|\}/g, '');//qipao
a = '`'+ a+'`'; if(that.checkForm[ky]){
let tem =a.match(reg)[0]; //替换变量
let ky = tem.replace(/\{|\}/g, '');//qipao a = a.replace(ky, 'yyy');
if(that.checkForm[ky]){ let yyy = "'"+that.checkForm[ky]+"'";
//替换变量 if(eval(eval( a))){
a = a.replace(ky, 'yyy'); tam += 'true';
let yyy = "'"+that.checkForm[ky]+"'";
if(eval(eval( a))){
tam += 'true';
}else{
tam += 'false';
}
}else{ }else{
tam += 'false'; tam += 'false';
} }
}
let rea = true;
if(rule.indexOf('||')>-1){
if( tam.indexOf('true')>-1){
rea = true;
}else{
rea = false;
}
}else{ }else{
if( tam.indexOf('false')>-1){ tam += 'false';
rea = false;
}else{
rea = true;
}
} }
if(rea){
that.formData[index].is_hidden = false;
}else{
that.formData[index].is_hidden = true;
that.checkForm[field_key] = null;
}
return rea;
}else{
let temp =rule.match(reg)[0];
let key = temp.replace(/\{|\}/g, '');//qipao
let a = rule.replace(key, 'yy');
a = a.replace(key, 'yy');
let yy = "'"+that.checkForm[key]+"'";
if(eval(eval(a))){
that.formData[index].is_hidden = false;
}else{
that.formData[index].is_hidden = true;
that.checkForm[field_key] = null;
}
return eval(eval(a));
} }
let rea = true;
if(rule.indexOf('||')>-1){
if( tam.indexOf('true')>-1){
rea = true;
}else{
rea = false;
}
}else{
if( tam.indexOf('false')>-1){
rea = false;
}else{
rea = true;
}
}
if(rea){
that.formData[index].is_hidden = false;
}else{
that.formData[index].is_hidden = true;
that.checkForm[field_key] = null;
}
return rea;
}else{ }else{
that.formData[index].is_hidden = true; let temp =rule.match(reg)[0];
that.checkForm[field_key] = null; let key = temp.replace(/\{|\}/g, '');//qipao
return false; let a = rule.replace(key, 'yy');
a = a.replace(key, 'yy');
let yy = "'"+that.checkForm[key]+"'";
if(eval(eval(a))){
that.formData[index].is_hidden = false;
}else{
that.formData[index].is_hidden = true;
that.checkForm[field_key] = null;
}
return eval(eval(a));
} }
}else{ }else{
that.formData[index].is_hidden = false; that.formData[index].is_hidden = false;

View File

@ -9,7 +9,7 @@
<el-row> <el-row>
<el-col <el-col
v-for="(item, $index) in formData" v-for="(item, $index) in formData"
v-show="filterBlock(item.parent,item.display_expression,$index,item.field_key)" v-show="filterBlock(item.display_expression,$index,item.field_key)"
:key="$index" :key="$index"
:span="12" :span="12"
style="position: relative" style="position: relative"
@ -375,78 +375,73 @@
} }
}, },
methods:{ methods:{
filterBlock(parent,rule,index,field_key){ filterBlock(rule,index,field_key){
// debugger; // debugger;
let that = this; let that = this;
if(parent!==''&&parent!==null&&parent!==undefined){ if(rule!==''&&rule!==null&&rule!==undefined){
if(rule!==''&&rule!==null&&rule!==undefined){ let reg = /\{(.+?)\}/g;
let reg = /\{(.+?)\}/g; debugger;
if(rule.indexOf('||')>-1||rule.indexOf('&&')>-1){ if(rule.indexOf('||')>-1||rule.indexOf('&&')>-1){
let tam = '', arr = []; let tam = '', arr = [];
if(rule.indexOf('||')>-1){ if(rule.indexOf('||')>-1){
arr = rule.split('||'); arr = rule.split('||');
}else{ }else{
arr = rule.split('&&'); arr = rule.split('&&');
} }
for (let i = 0;i<arr.length;i++){ for (let i = 0;i<arr.length;i++){
//获取判断依据 //获取判断依据
let a = ''; let a = '';
a = arr[i].replace(/`/g,''); a = arr[i].replace(/`/g,'');
a = '`'+ a+'`'; a = '`'+ a+'`';
let tem =a.match(reg)[0]; let tem =a.match(reg)[0];
let ky = tem.replace(/\{|\}/g, '');//qipao let ky = tem.replace(/\{|\}/g, '');//qipao
if(that.checkForm[ky]){ if(that.checkForm[ky]){
//替换变量 //替换变量
a = a.replace(ky, 'yyy'); a = a.replace(ky, 'yyy');
let yyy = "'"+that.checkForm[ky]+"'"; let yyy = "'"+that.checkForm[ky]+"'";
if(eval(eval( a))){ if(eval(eval( a))){
tam += 'true'; tam += 'true';
}else{
tam += 'false';
}
}else{ }else{
tam += 'false'; tam += 'false';
} }
}
let rea = true;
if(rule.indexOf('||')>-1){
if( tam.indexOf('true')>-1){
rea = true;
}else{
rea = false;
}
}else{ }else{
if( tam.indexOf('false')>-1){ tam += 'false';
rea = false;
}else{
rea = true;
}
} }
if(rea){
that.formData[index].is_hidden = false;
}else{
that.formData[index].is_hidden = true;
that.checkForm[field_key] = null;
}
return rea;
}else{
let temp =rule.match(reg)[0];
let key = temp.replace(/\{|\}/g, '');//qipao
let a = rule.replace(key, 'yy');
a = a.replace(key, 'yy');
let yy = "'"+that.checkForm[key]+"'";
if(eval(eval(a))){
that.formData[index].is_hidden = false;
}else{
that.formData[index].is_hidden = true;
that.checkForm[field_key] = null;
}
return eval(eval(a));
} }
let rea = true;
if(rule.indexOf('||')>-1){
if( tam.indexOf('true')>-1){
rea = true;
}else{
rea = false;
}
}else{
if( tam.indexOf('false')>-1){
rea = false;
}else{
rea = true;
}
}
if(rea){
that.formData[index].is_hidden = false;
}else{
that.formData[index].is_hidden = true;
that.checkForm[field_key] = null;
}
return rea;
}else{ }else{
that.formData[index].is_hidden = true; let temp =rule.match(reg)[0];
that.checkForm[field_key] = null; let key = temp.replace(/\{|\}/g, '');//qipao
return false; let a = rule.replace(key, 'yy');
a = a.replace(key, 'yy');
let yy = "'"+that.checkForm[key]+"'";
if(eval(eval(a))){
that.formData[index].is_hidden = false;
}else{
that.formData[index].is_hidden = true;
that.checkForm[field_key] = null;
}
return eval(eval(a));
} }
}else{ }else{
that.formData[index].is_hidden = false; that.formData[index].is_hidden = false;

View File

@ -9,14 +9,21 @@
<Echart <Echart
:options="pieOptions" :options="pieOptions"
id="pieChart" id="pieChart"
height="45vh" :height="domHeight"
></Echart> ></Echart>
</el-card> </el-card>
</el-col> </el-col>
<el-col :span="16"> <el-col :span="16">
<el-card> <el-card>
<div class="chartsTitle">废料原因统计</div> <div class="chartsTitle">废料原因统计</div>
<div id="barChart" style="width:100%;height: 45vh"></div> <charts
:id="chartId0"
:options="barOptions1"
:className="chartsName"
:height="domHeight"
width="600px"
>
</charts>
</el-card> </el-card>
</el-col> </el-col>
</el-row> </el-row>
@ -54,9 +61,9 @@
<div class="chartsTitle">采购物料表</div> <div class="chartsTitle">采购物料表</div>
<charts <charts
:id="chartId1" :id="chartId1"
:options="barOptions" :options="barOptions21"
:className="chartsName" :className="chartsName"
height="45vh" :height="domHeight"
width="600px" width="600px"
> >
</charts> </charts>
@ -67,9 +74,9 @@
<div class="chartsTitle">采购供应商表</div> <div class="chartsTitle">采购供应商表</div>
<charts <charts
:id="chartId2" :id="chartId2"
:options="barOptions" :options="barOptions22"
:className="chartsName" :className="chartsName"
height="45vh" :height="domHeight"
width="600px" width="600px"
> >
</charts> </charts>
@ -109,9 +116,9 @@
<div class="chartsTitle">废料来源</div> <div class="chartsTitle">废料来源</div>
<charts <charts
:id="chartId3" :id="chartId3"
:options="barOptions" :options="barOptions3"
:className="chartsName" :className="chartsName"
height="45vh" :height="domHeight"
> >
</charts> </charts>
</el-card> </el-card>
@ -157,17 +164,21 @@
}, },
data() { data() {
return { return {
chartId0: 'chart0',
chartId1: 'chart1', chartId1: 'chart1',
chartId2: 'chart2', chartId2: 'chart2',
chartId3: 'chart3', chartId3: 'chart3',
barChart: null, barChart: null,
barChart1: null, barChart1: null,
pieOptions: {}, pieOptions: {},
barOptions: {}, barOptions1: {},
barOptions21: {},
barOptions22: {},
barOptions3: {},
activeName: '废料统计', activeName: '废料统计',
chartsName: "chartsName", chartsName: "chartsName",
domHeight:'300px',
cdata: { cdata: {
xData: ["气泡", "划痕"],
seriesData: [ seriesData: [
{value: 10, name: "气泡"}, {value: 10, name: "气泡"},
{value: 5, name: "破点"}, {value: 5, name: "破点"},
@ -175,12 +186,22 @@
{value: 6, name: "其他"}, {value: 6, name: "其他"},
] ]
}, },
chartData: { chartData1: {
xAxisData: ["气泡", "破点", "划伤", "其他"], xAxisData: ["气泡", "破点", "划伤", "其他"],
seriesData: [10, 5, 19, 6], seriesData: [30, 25, 35, 10],
},
chartData21: {
xAxisData: ["物料1", "物料2", "物料3", "物料4", "物料5", "物料6", "物料7"],
seriesData: [800, 950, 960, 906, 600, 800, 900],
},
chartData22: {
xAxisData: ["供应商1", "供应商2", "供应商3", "供应商4", "供应商5", "供应商6", "供应商7"],
seriesData: [5, 20, 15, 25,10, 10,15],
},
chartData3: {
xAxisData: ["供应商1", "供应商2", "供应商3", "供应商4", "供应商5", "供应商6", "供应商7"],
seriesData:[2, 2, 4, 5,1, 0,1],
}, },
xAxisbar: ["供应商1", "供应商2", "供应商3", "供应商4", "供应商5", "供应商6", "供应商7"],
barData: [80, 95, 96, 96, 96, 98, 99],
list: [ list: [
{id: 1, name: 'HIehd91', card: '3331', sco: 'REF-31', num: 2, reason: "气泡"}, {id: 1, name: 'HIehd91', card: '3331', sco: 'REF-31', num: 2, reason: "气泡"},
{id: 2, name: 'HIehd92', card: '3332', sco: 'REF-32', num: 1, reason: "划痕"}, {id: 2, name: 'HIehd92', card: '3332', sco: 'REF-32', num: 1, reason: "划痕"},
@ -233,87 +254,22 @@
immediate: true, immediate: true,
deep: true deep: true
}, },
created(){
let hei = document.getElementsByClassName('app-main')[0].clientHeight;
this.domHeight =( hei- 20)/2+'px';
},
methods: { methods: {
drawChart() { handleClick() {
let that = this;
this.barChart = this.$echarts.init(document.getElementById('barChart'));
this.barChart.setOption({
grid: {
top: '10%',
left: '3%',
right: '5%',
bottom: '1%',
containLabel: true
},
tooltip: {
trigger: 'item',
formatter: function (params) {
let color = params.color;//图例颜色
let htmlStr = '<div>';
htmlStr += params.seriesName + '<br/>';
htmlStr += '<span style="height:10px;width:10px;font-size:12px;border-radius:5px;margin-right:5px;font-family:Consolas;display:inline-block;background:' + color + ';"></span>';
htmlStr += params.name + '' + params.value + '';
htmlStr += '</div>';
return htmlStr;
}
},
xAxis: {
axisTick: {
show: false
},
splitLine: {
show: false, //去掉X轴分割线
},
data: that.chartData.xAxisData,
},
yAxis: {
axisLine: {
show: true,//y轴线
},
axisTick: {
show: false//Y轴刻度线
},
axisLabel: {
color: '#333333'//Y轴文本颜色
},
splitLine: {
show: true, //Y轴分割线
lineStyle: {
color: '#dddddd'//Y轴分割线颜色
}
},
},
series: [{
name: '废料统计',
type: 'bar',
barWidth: 20,
data: that.chartData.seriesData,
label: {
show: true, //开启显示
position: 'top', //在上方显示
formatter: '{c}',//显示百分号
textStyle: { //数值样式
color: 'black',//字体颜色
fontSize: 10//字体大小
}
},
itemStyle: {
color: '#409EFF'
},
}]
});
},
handleClick(tab) {
// console.log(tab); // console.log(tab);
// debugger; // debugger;
}, },
}, },
mounted() { mounted() {
this.drawChart(); let that = this;
this.barOptions = { this.barOptions1 = {
grid: { grid: {
top: '10%', top: '10%',
left: '3%', left: '5%',
right: '5%', right: '5%',
bottom: '1%', bottom: '1%',
containLabel: true containLabel: true
@ -323,9 +279,9 @@
formatter: function (params) { formatter: function (params) {
let color = params.color;//图例颜色 let color = params.color;//图例颜色
let htmlStr = '<div>'; let htmlStr = '<div>';
htmlStr += params.name + '<br/>'; htmlStr += params.seriesName + '<br/>';
htmlStr += '<span style="height:10px;width:10px;font-size:12px;border-radius:5px;margin-right:5px;font-family:Consolas;display:inline-block;background:' + color + ';"></span>'; htmlStr += '<span style="height:10px;width:10px;font-size:12px;border-radius:5px;margin-right:5px;font-family:Consolas;display:inline-block;background:' + color + ';"></span>';
htmlStr += params.seriesName + '' + params.value + '%'; htmlStr += params.name + '' + params.value + '';
htmlStr += '</div>'; htmlStr += '</div>';
return htmlStr; return htmlStr;
} }
@ -337,7 +293,7 @@
splitLine: { splitLine: {
show: false, //去掉X轴分割线 show: false, //去掉X轴分割线
}, },
data: this.xAxisbar, data: that.chartData1.xAxisData,
}, },
yAxis: { yAxis: {
axisLine: { axisLine: {
@ -357,10 +313,10 @@
}, },
}, },
series: [{ series: [{
name: '成品率', name: '废料统计',
type: 'bar', type: 'bar',
barWidth: 20, barWidth: 20,
data: this.barData, data: that.chartData1.seriesData,
label: { label: {
show: true, //开启显示 show: true, //开启显示
position: 'top', //在上方显示 position: 'top', //在上方显示
@ -374,7 +330,202 @@
color: '#409EFF' color: '#409EFF'
}, },
}] }]
} };
this.barOptions21 = {
grid: {
top: '10%',
left: '5%',
right: '5%',
bottom: '1%',
containLabel: true
},
tooltip: {
trigger: 'item',
formatter: function (params) {
let color = params.color;//图例颜色
let htmlStr = '<div>';
htmlStr += '物料采购' + '<br/>';
htmlStr += '<span style="height:10px;width:10px;font-size:12px;border-radius:5px;margin-right:5px;font-family:Consolas;display:inline-block;background:' + color + ';"></span>';
htmlStr += params.name + '' + params.value + '';
htmlStr += '</div>';
return htmlStr;
}
},
xAxis: {
axisTick: {
show: false
},
splitLine: {
show: false, //去掉X轴分割线
},
data: this.chartData21.xAxisData,
},
yAxis: {
axisLine: {
show: true,//y轴线
},
axisTick: {
show: false//Y轴刻度线
},
axisLabel: {
color: '#333333'//Y轴文本颜色
},
splitLine: {
show: true, //Y轴分割线
lineStyle: {
color: '#dddddd'//Y轴分割线颜色
}
},
},
series: [{
name: '物料',
type: 'bar',
barWidth: 20,
data: this.chartData21.seriesData,
label: {
show: true, //开启显示
position: 'top', //在上方显示
formatter: '{c}',//显示百分号
textStyle: { //数值样式
color: 'black',//字体颜色
fontSize: 10//字体大小
}
},
itemStyle: {
color: '#409EFF'
},
}]
};
this.barOptions22 = {
grid: {
top: '10%',
left: '5%',
right: '5%',
bottom: '1%',
containLabel: true
},
tooltip: {
trigger: 'item',
formatter: function (params) {
let color = params.color;//图例颜色
let htmlStr = '<div>';
htmlStr += params.seriesName + '<br/>';
htmlStr += '<span style="height:10px;width:10px;font-size:12px;border-radius:5px;margin-right:5px;font-family:Consolas;display:inline-block;background:' + color + ';"></span>';
htmlStr += params.name + '' + params.value + '%';
htmlStr += '</div>';
return htmlStr;
}
},
xAxis: {
axisTick: {
show: false
},
splitLine: {
show: false, //去掉X轴分割线
},
data: this.chartData22.xAxisData,
},
yAxis: {
axisLine: {
show: true,//y轴线
},
axisTick: {
show: false//Y轴刻度线
},
axisLabel: {
color: '#333333'//Y轴文本颜色
},
splitLine: {
show: true, //Y轴分割线
lineStyle: {
color: '#dddddd'//Y轴分割线颜色
}
},
},
series: [{
name: '采购占比',
type: 'bar',
barWidth: 20,
data: this.chartData22.seriesData,
label: {
show: true, //开启显示
position: 'top', //在上方显示
formatter: '{c}',//显示百分号
textStyle: { //数值样式
color: 'black',//字体颜色
fontSize: 10//字体大小
}
},
itemStyle: {
color: '#409EFF'
},
}]
};
this.barOptions3 = {
grid: {
top: '10%',
left: '5%',
right: '5%',
bottom: '1%',
containLabel: true
},
tooltip: {
trigger: 'item',
formatter: function (params) {
let color = params.color;//图例颜色
let htmlStr = '<div>';
htmlStr += params.seriesName + '<br/>';
htmlStr += '<span style="height:10px;width:10px;font-size:12px;border-radius:5px;margin-right:5px;font-family:Consolas;display:inline-block;background:' + color + ';"></span>';
htmlStr += params.name + '' + params.value + '';
htmlStr += '</div>';
return htmlStr;
}
},
xAxis: {
axisTick: {
show: false
},
splitLine: {
show: false, //去掉X轴分割线
},
data: this.chartData3.xAxisData,
},
yAxis: {
axisLine: {
show: true,//y轴线
},
axisTick: {
show: false//Y轴刻度线
},
axisLabel: {
color: '#333333'//Y轴文本颜色
},
splitLine: {
show: true, //Y轴分割线
lineStyle: {
color: '#dddddd'//Y轴分割线颜色
}
},
},
series: [{
name: '废料来源',
type: 'bar',
barWidth: 20,
data: this.chartData3.seriesData,
label: {
show: true, //开启显示
position: 'top', //在上方显示
formatter: '{c}',//显示百分号
textStyle: { //数值样式
color: 'black',//字体颜色
fontSize: 10//字体大小
}
},
itemStyle: {
color: '#409EFF'
},
}]
};
} }
} }
</script> </script>

View File

@ -7,7 +7,7 @@
<Echart <Echart
:options="pieOptions" :options="pieOptions"
id="pieChart" id="pieChart"
height="45vh" :height="domHeight"
></Echart> ></Echart>
</el-card> </el-card>
</el-col> </el-col>
@ -18,7 +18,7 @@
:id="chartId1" :id="chartId1"
:options="barOptions" :options="barOptions"
:className="chartsName" :className="chartsName"
height="45vh" :height="domHeight"
width="100%" width="100%"
> >
</charts> </charts>
@ -31,7 +31,7 @@
:id="chartId2" :id="chartId2"
:options="barOptions1" :options="barOptions1"
:className="chartsName" :className="chartsName"
height="45vh" :height="domHeight"
width="100%" width="100%"
> >
</charts> </charts>
@ -54,7 +54,6 @@
v-el-height-adaptive-table="{bottomOffset: 42}" v-el-height-adaptive-table="{bottomOffset: 42}"
> >
<el-table-column type="index" width="50" /> <el-table-column type="index" width="50" />
<el-table-column label="订单编号" width="120" show-overflow-tooltip> <el-table-column label="订单编号" width="120" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.number }}</template> <template slot-scope="scope">{{ scope.row.number }}</template>
</el-table-column> </el-table-column>
@ -64,7 +63,6 @@
<el-table-column label="产品数量"> <el-table-column label="产品数量">
<template slot-scope="scope">{{ scope.row.count }}</template> <template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column> </el-table-column>
<el-table-column label="已交货数量"> <el-table-column label="已交货数量">
<template slot-scope="scope">{{ scope.row.delivered_count }}</template> <template slot-scope="scope">{{ scope.row.delivered_count }}</template>
</el-table-column> </el-table-column>
@ -168,6 +166,7 @@
{value: 1, name: "逾期率"}, {value: 1, name: "逾期率"},
] ]
}, },
domHeight:'300px',
xAxisbar:["冷加工", "热弯", "钢化", "镀膜", "夹层", "包边", "装框"], xAxisbar:["冷加工", "热弯", "钢化", "镀膜", "夹层", "包边", "装框"],
barData: [80, 95, 96, 96, 96, 98, 99], barData: [80, 95, 96, 96, 96, 98, 99],
xAxisbar1:[ "2021/09", "2021/10", "2021/11", "2021/12", "2022/01", "2022/02"], xAxisbar1:[ "2021/09", "2021/10", "2021/11", "2021/12", "2022/01", "2022/02"],
@ -217,6 +216,10 @@
immediate: true, immediate: true,
deep: true deep: true
}, },
created(){
let hei = document.getElementsByClassName('app-main')[0].clientHeight;
this.domHeight =( hei- 60)/2+'px';
},
methods: { methods: {
getList() { getList() {
this.orderLoading = true; this.orderLoading = true;
@ -378,6 +381,7 @@
}, },
}] }]
} }
} }
} }
</script> </script>

View File

@ -1008,25 +1008,23 @@
handleInspection(scope, index) { handleInspection(scope, index) {
//调该物料对应的检查表 //调该物料对应的检查表
let that = this; let that = this;
this.innerIndex = index; that.innerIndex = index;
// this.outerVisible = true; // this.outerVisible = true;
this.wproduct = scope.row.id;//半成品ID that.wproduct = scope.row.id;//半成品ID
debugger; that.listQueryrecordform.material = scope.row.material;
console.log(scope.row.material_check); that.listQueryrecordform.type = 20;
this.listQueryrecordform.material = scope.row.material_check!==null ? scope.row.material_check :scope.row.material;// that.listQueryrecordform.enabled = true;
this.listQueryrecordform.type = 2; that.recordform = null;
this.listQueryrecordform.enabled = true; getrecordformList(that.listQueryrecordform).then((response) => {
this.recordform = null;
getrecordformList(this.listQueryrecordform).then((response) => {
if (response.data) { if (response.data) {
this.recordformList = response.data; that.recordformList = response.data;
if (response.data.length === 1) { if (response.data.length === 1) {
that.recordform = response.data[0].id; that.recordform = response.data[0].id;
that.formName = response.data[0].name; that.formName = response.data[0].name;
that.submitrecordform(index); that.submitrecordform(index);
} else { } else {
//弹出列表选择框 //弹出列表选择框
this.outerVisible = true; that.outerVisible = true;
} }
} }
}); });
@ -1038,8 +1036,6 @@
return item.id === that.recordform; return item.id === that.recordform;
}); });
that.formName = arr[0].name; that.formName = arr[0].name;
// this.outerVisible = false;
// that.submitrecordform(that.innerIndex);
}, },
//检验记录 //检验记录
checkRecord(scope, index) { checkRecord(scope, index) {

View File

@ -4,7 +4,7 @@ from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelM
from apps.mtm.filters import MaterialFilterSet, TechDocFilterset from apps.mtm.filters import MaterialFilterSet, TechDocFilterset
from apps.mtm.models import Material, PackItem, Process, RecordForm, RecordFormField, Step, SubprodctionMaterial, TechDoc, UsedStep, SubProduction from apps.mtm.models import Material, PackItem, Process, RecordForm, RecordFormField, Step, SubprodctionMaterial, TechDoc, UsedStep, SubProduction
from apps.mtm.serializers import InputMaterialSerializer, InputMaterialUpdateSerializer, MaterialDetailSerializer, MaterialSerializer, MaterialSimpleSerializer, OtherMaterialSerializer, OutputMaterialSerializer, OutputMaterialUpdateSerializer, PackItemCreateSerializer, PackItemUpdateSerializer, ProcessSerializer, RecordFormCreateSerializer, RecordFormDetailSerializer, RecordFormFieldCreateSerializer, RecordFormFieldSerializer, RecordFormFieldUpdateSerializer, RecordFormSerializer, RecordFormUpdateSerializer, StepDetailSerializer, StepSerializer, SubProductionCreateUpdateSerializer, SubProductionSerializer, SubprodctionMaterialListSerializer, TechDocCreateSerializer, TechDocListSerializer, TechDocUpdateSerializer, UsedStepCreateSerializer, UsedStepListSerializer, UsedStepUpdateSerializer from apps.mtm.serializers import InputMaterialSerializer, InputMaterialUpdateSerializer, MaterialDetailSerializer, MaterialSerializer, MaterialSimpleSerializer, OtherMaterialSerializer, OutputMaterialSerializer, OutputMaterialUpdateSerializer, PackItemCreateSerializer, PackItemSerializer, PackItemUpdateSerializer, ProcessSerializer, RecordFormCreateSerializer, RecordFormDetailSerializer, RecordFormFieldCreateSerializer, RecordFormFieldSerializer, RecordFormFieldUpdateSerializer, RecordFormSerializer, RecordFormUpdateSerializer, StepDetailSerializer, StepSerializer, SubProductionCreateUpdateSerializer, SubProductionSerializer, SubprodctionMaterialListSerializer, TechDocCreateSerializer, TechDocListSerializer, TechDocUpdateSerializer, UsedStepCreateSerializer, UsedStepListSerializer, UsedStepUpdateSerializer
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.response import Response from rest_framework.response import Response
@ -38,7 +38,7 @@ class PackItemViewSet(CreateUpdateModelAMixin, ModelViewSet):
perms_map = {'get': '*', 'post': 'packitem_create', perms_map = {'get': '*', 'post': 'packitem_create',
'put': 'packitem_update', 'delete': 'packitem_delete'} 'put': 'packitem_update', 'delete': 'packitem_delete'}
queryset = PackItem.objects.all() queryset = PackItem.objects.all()
serializer_class = MaterialSerializer serializer_class = PackItemSerializer
search_fields = ['name', 'number'] search_fields = ['name', 'number']
filterset_fields = ['material'] filterset_fields = ['material']
ordering = ['sort'] ordering = ['sort']

View File

@ -0,0 +1,45 @@
# Generated by Django 3.2.9 on 2022-02-18 08:16
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('mtm', '0047_packitem'),
('pm', '0024_auto_20220217_1524'),
]
operations = [
migrations.AddField(
model_name='subproductionplan',
name='first_tester',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='首件检查员'),
),
migrations.AddField(
model_name='subproductionplan',
name='is_first_testok',
field=models.BooleanField(default=True, verbose_name='首件是否合格'),
),
migrations.CreateModel(
name='FirstItem',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('field_value', models.JSONField(blank=True, null=True, verbose_name='录入值')),
('is_hidden', models.BooleanField(default=False, verbose_name='是否隐藏')),
('is_testok', models.BooleanField(blank=True, null=True, verbose_name='是否合格')),
('form_field', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.recordformfield', verbose_name='关联自定义表格字段')),
('subproduction_plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='item_test_record', to='pm.subproductionplan', verbose_name='关联的子计划')),
],
options={
'abstract': False,
},
),
]

View File

@ -0,0 +1,65 @@
# Generated by Django 3.2.9 on 2022-02-18 08:36
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('mtm', '0047_packitem'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('pm', '0025_auto_20220218_1616'),
]
operations = [
migrations.RemoveField(
model_name='subproductionplan',
name='first_tester',
),
migrations.RemoveField(
model_name='subproductionplan',
name='is_first_testok',
),
migrations.AddField(
model_name='subproductionplan',
name='first_sign_time',
field=models.DateTimeField(blank=True, null=True, verbose_name='首件签字时间'),
),
migrations.AddField(
model_name='subproductionplan',
name='form',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mtm.recordform', verbose_name='首件检查表'),
),
migrations.AddField(
model_name='subproductionplan',
name='is_testok',
field=models.BooleanField(blank=True, null=True, verbose_name='首件是否合格'),
),
migrations.AddField(
model_name='subproductionplan',
name='leader_1',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='first_leader_1', to=settings.AUTH_USER_MODEL, verbose_name='工序负责人'),
),
migrations.AddField(
model_name='subproductionplan',
name='leader_2',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='first_leader_2', to=settings.AUTH_USER_MODEL, verbose_name='技术负责人'),
),
migrations.AddField(
model_name='subproductionplan',
name='leader_3',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='first_leader_3', to=settings.AUTH_USER_MODEL, verbose_name='总检'),
),
migrations.AddField(
model_name='subproductionplan',
name='remark',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='备注'),
),
migrations.AddField(
model_name='subproductionplan',
name='tester',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='first_tester', to=settings.AUTH_USER_MODEL, verbose_name='首件检查员'),
),
]

View File

@ -0,0 +1,35 @@
# Generated by Django 3.2.9 on 2022-02-21 02:27
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('qm', '0025_alter_testrecord_type'),
('pm', '0026_auto_20220218_1636'),
]
operations = [
migrations.RemoveField(
model_name='subproductionplan',
name='form',
),
migrations.RemoveField(
model_name='subproductionplan',
name='is_testok',
),
migrations.RemoveField(
model_name='subproductionplan',
name='tester',
),
migrations.AddField(
model_name='subproductionplan',
name='first_test',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='qm.testrecord'),
),
migrations.DeleteModel(
name='FirstItem',
),
]

View File

@ -1,5 +1,5 @@
from io import open_code
from apps.system.models import CommonAModel, Organization from apps.system.models import CommonAModel, Organization, User
from django.db import models from django.db import models
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser
from django.db.models.base import Model from django.db.models.base import Model
@ -7,7 +7,7 @@ import django.utils.timezone as timezone
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from utils.model import SoftModel, BaseModel from utils.model import SoftModel, BaseModel
from apps.mtm.models import Material, Process, RecordFormField, SubProduction, SubprodctionMaterial from apps.mtm.models import Material, Process, RecordForm, RecordFormField, SubProduction, SubprodctionMaterial
from apps.sam.models import Order from apps.sam.models import Order
class ProductionPlan(CommonAModel): class ProductionPlan(CommonAModel):
@ -69,6 +69,7 @@ class SubProductionPlan(CommonAModel):
(SUBPLAN_STATE_WORKING, '生产中'), (SUBPLAN_STATE_WORKING, '生产中'),
(SUBPLAN_STATE_DONE, '已完成'), (SUBPLAN_STATE_DONE, '已完成'),
) )
number = models.CharField('子计划编号', max_length=50, unique=True, null=True, blank=True) number = models.CharField('子计划编号', max_length=50, unique=True, null=True, blank=True)
production_plan = models.ForeignKey(ProductionPlan, verbose_name='关联主生产计划', on_delete=models.CASCADE, related_name='subplan_plan') production_plan = models.ForeignKey(ProductionPlan, verbose_name='关联主生产计划', on_delete=models.CASCADE, related_name='subplan_plan')
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE, related_name='subplan_subprod') subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE, related_name='subplan_subprod')
@ -91,21 +92,20 @@ class SubProductionPlan(CommonAModel):
end_date_real = models.DateField('实际完工日期', null=True, blank=True) end_date_real = models.DateField('实际完工日期', null=True, blank=True)
is_picked = models.BooleanField('是否已领料', default=False) is_picked = models.BooleanField('是否已领料', default=False)
# wproducts = models.JSONField('半成品表', default=list, blank=True) first_test = models.ForeignKey('qm.testrecord', on_delete=models.CASCADE, null=True, blank=True)
leader_1 = models.ForeignKey(User, on_delete=models.CASCADE,
verbose_name="工序负责人", null=True, blank=True, related_name='first_leader_1')
leader_2 = models.ForeignKey(User, on_delete=models.CASCADE,
verbose_name="技术负责人", null=True, blank=True, related_name='first_leader_2')
leader_3 = models.ForeignKey(User, on_delete=models.CASCADE,
verbose_name="总检", null=True, blank=True, related_name='first_leader_3')
first_sign_time = models.DateTimeField('首件签字时间', null=True, blank=True)
remark = models.CharField('备注', max_length=100, null=True, blank=True)
class Meta: class Meta:
verbose_name = '子生产计划' verbose_name = '子生产计划'
verbose_name_plural = verbose_name verbose_name_plural = verbose_name
# class FirstItem(BaseModel):
# """
# 首件确认表记录条目
# """
# form_field = models.ForeignKey(RecordFormField, verbose_name='关联自定义表格字段', on_delete=models.CASCADE)
# field_value = models.JSONField('录入值', null=True, blank=True)
# is_hidden = models.BooleanField('是否隐藏', default=False)
# is_testok = models.BooleanField('是否合格', null=True, blank=True)
# subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联的子计划', on_delete=models.CASCADE, related_name='item_test_record')
class SubProductionProgress(BaseModel): class SubProductionProgress(BaseModel):
""" """
子计划生产进度统计表/物料消耗 子计划生产进度统计表/物料消耗

View File

@ -1,8 +1,10 @@
from apps.mtm.models import RecordForm
from apps.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress from apps.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress
from rest_framework import serializers from rest_framework import serializers
from apps.qm.serializers import TestRecordShortSerializer
from apps.sam.serializers import OrderSerializer, OrderSimpleSerializer from apps.sam.serializers import OrderSerializer, OrderSimpleSerializer
from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer, SubProductionSimpleSerializer from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer, RecordFormSimpleSerializer, SubProductionSimpleSerializer
from apps.system.serializers import OrganizationSimpleSerializer from apps.system.serializers import OrganizationSimpleSerializer, UserSimpleSerializer
from utils.mixins import DynamicFieldsSerializerMixin from utils.mixins import DynamicFieldsSerializerMixin
@ -32,12 +34,16 @@ class ResourceConvertListSerializer(serializers.ListSerializer):
class ResourceCalListSerializer(serializers.ListSerializer): class ResourceCalListSerializer(serializers.ListSerializer):
child = ResourceCalSerializer() child = ResourceCalSerializer()
class SubProductionPlanListSerializer(serializers.ModelSerializer): class SubProductionPlanListSerializer(DynamicFieldsSerializerMixin, serializers.ModelSerializer):
workshop_ = OrganizationSimpleSerializer(source='workshop', read_only=True) workshop_ = OrganizationSimpleSerializer(source='workshop', read_only=True)
process_ = ProcessSimpleSerializer(source='process', read_only=True) process_ = ProcessSimpleSerializer(source='process', read_only=True)
subproduction_ = SubProductionSimpleSerializer(source='subproduction', read_only=True) subproduction_ = SubProductionSimpleSerializer(source='subproduction', read_only=True)
product_ = MaterialSimpleSerializer(source='product', read_only=True) product_ = MaterialSimpleSerializer(source='product', read_only=True)
plan_product_ = serializers.SerializerMethodField() plan_product_ = serializers.SerializerMethodField()
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)
class Meta: class Meta:
model=SubProductionPlan model=SubProductionPlan
fields = '__all__' fields = '__all__'
@ -75,3 +81,12 @@ class SubProductionProgressSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = SubProductionProgress model = SubProductionProgress
fields = '__all__' fields = '__all__'
class FirstTestInitSerializer(serializers.Serializer):
form = serializers.PrimaryKeyRelatedField(queryset=RecordForm.objects.all(), required=True)
class FirstTestAuditSerializer(serializers.Serializer):
leader = serializers.CharField()
base64 = serializers.CharField()

View File

@ -5,23 +5,27 @@ from rest_framework import serializers
from rest_framework.views import APIView from rest_framework.views import APIView
from apps.em.models import Equipment from apps.em.models import Equipment
from apps.em.serializers import EquipmentSimpleSerializer from apps.em.serializers import EquipmentSimpleSerializer
from apps.hrm.services import HRMService
from apps.inm.models import MaterialBatch from apps.inm.models import MaterialBatch
from apps.inm.serializers import MaterialBatchSerializer from apps.inm.serializers import MaterialBatchSerializer
from apps.mtm.models import Material, Step, SubProduction, SubprodctionMaterial from apps.mtm.models import Material, RecordFormField, Step, SubProduction, SubprodctionMaterial
from apps.pm.filters import PlanFilterSet, SubproductionProgressFilterSet from apps.pm.filters import PlanFilterSet, SubproductionProgressFilterSet
from apps.qm.models import TestRecord, TestRecordItem
from apps.system.mixins import CreateUpdateModelAMixin from apps.system.mixins import CreateUpdateModelAMixin
from apps.pm.serializers import GenSubPlanSerializer, PickNeedSerializer, PlanDestorySerializer, ProductionPlanCreateFromOrderSerializer, ProductionPlanSerializer, ResourceCalListSerializer, ResourceCalSerializer, ResourceConvertListSerializer, ResourceConvertSerializer, SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer, SubProductionProgressSerializer from apps.pm.serializers import FirstTestAuditSerializer, FirstTestInitSerializer, GenSubPlanSerializer, PickNeedSerializer, PlanDestorySerializer, ProductionPlanCreateFromOrderSerializer, ProductionPlanSerializer, ResourceCalListSerializer, ResourceCalSerializer, ResourceConvertListSerializer, ResourceConvertSerializer, SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer, SubProductionProgressSerializer
from rest_framework.mixins import CreateModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin from rest_framework.mixins import CreateModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
from apps.pm.models import ProductionPlan, SubProductionProgress, SubProductionPlan from apps.pm.models import ProductionPlan, SubProductionProgress, SubProductionPlan
from rest_framework.viewsets import GenericViewSet, ModelViewSet from rest_framework.viewsets import GenericViewSet, ModelViewSet
from django.shortcuts import render from django.shortcuts import render
from apps.sam.models import Order from apps.sam.models import Order
from rest_framework.exceptions import APIException, ParseError from rest_framework.exceptions import APIException, ParseError, ValidationError
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.decorators import action from rest_framework.decorators import action
from django.db.models import F from django.db.models import F
from utils.tools import ranstr from utils.tools import ranstr
from django.db import transaction from django.db import transaction
from rest_framework import status
from django.utils import timezone
# Create your views here. # Create your views here.
def updateOrderPlanedCount(order): def updateOrderPlanedCount(order):
@ -145,7 +149,9 @@ class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateMo
子生产计划-列表/修改 子生产计划-列表/修改
""" """
perms_map = {'get': '*', 'put':'subplan_update'} perms_map = {'get': '*', 'put':'subplan_update'}
queryset = SubProductionPlan.objects.select_related('process', 'workshop', 'subproduction', 'product', 'production_plan__product') queryset = SubProductionPlan.objects.select_related('process',
'workshop', 'subproduction', 'product',
'production_plan__product', 'leader_1', 'leader_2', 'leader_3')
search_fields = [] search_fields = []
serializer_class = SubProductionPlanListSerializer serializer_class = SubProductionPlanListSerializer
filterset_fields = ['production_plan', 'process', 'state', 'product', 'workshop'] filterset_fields = ['production_plan', 'process', 'state', 'product', 'workshop']
@ -229,6 +235,67 @@ class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateMo
have = MaterialBatchSerializer(instance=objs, many=True).data have = MaterialBatchSerializer(instance=objs, many=True).data
return Response({'need':need, 'have':have}) return Response({'need':need, 'have':have})
@action(methods=['post'], detail=True, perms_map={'post':'first_test'}, serializer_class=FirstTestInitSerializer)
@transaction.atomic
def first_test_init(self, request, pk=None):
"""
首件检查表初始化
"""
obj = self.get_object()
if obj.first_test is None:
rdata = request.data
serializer = self.get_serializer(data=rdata)
serializer.is_valid(raise_exception=True)
form = serializer.validated_data.get('form')
savedict = dict(
create_by=request.user,
subproduction_plan=obj,
type = TestRecord.TEST_FIRST,
form=form)
tr = TestRecord.objects.create(**savedict)
for i in RecordFormField.objects.filter(form=form, is_deleted=False):
tri = TestRecordItem()
tri.test_record = tr
tri.form_field = i
tri.is_hidden = i.is_hidden
tri.create_by = request.user
tri.save()
return Response()
raise APIException('首件检查已存在')
@action(methods=['post'], detail=True, perms_map={'post':'first_test_audit'}, serializer_class=FirstTestAuditSerializer)
@transaction.atomic
def first_audit(self, request, pk=None):
obj = self.get_object()
if obj.leader_1 and obj.leader_2 and obj.leader_3:
raise ValidationError('首件确认已完成')
if obj.first_test is None:
raise ValidationError('未进行首件检查')
if not obj.first_test.is_submited:
raise ValidationError('首件检查未提交')
if not obj.first_test.is_testok:
raise ValidationError('首件检查不合格')
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data
user, msg = HRMService.face_compare_from_base64(vdata.get('base64'))
if user:
le = vdata.get('leader')
if le not in ['leader_1', 'leader_2', 'leader_3']:
return Response('审核人有误', status=status.HTTP_400_BAD_REQUEST)
if vdata.get('leader') == 'leader_1':
obj.leader_1 = user
elif vdata.get('leader') == 'leader_2':
obj.leader_2 = user
else:
obj.leader_3 = user
obj.first_sign_time = timezone.now()
obj.save()
return Response()
return Response(msg, status=status.HTTP_400_BAD_REQUEST)
class SubProductionProgressViewSet(ListModelMixin, GenericViewSet): class SubProductionProgressViewSet(ListModelMixin, GenericViewSet):
""" """
生产进度 生产进度

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.9 on 2022-02-21 02:27
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('qm', '0024_rename_is_midtesing_testrecord_is_midtesting'),
]
operations = [
migrations.AlterField(
model_name='testrecord',
name='type',
field=models.PositiveSmallIntegerField(choices=[(20, '工序检验'), (30, '工序复检'), (36, '夹层检验'), (40, '成品检验'), (10, '首件检验')], default=20),
),
]

View File

@ -47,6 +47,7 @@ class TestRecord(CommonADModel):
""" """
检验记录 检验记录
""" """
TEST_FIRST = 10
TEST_PROCESS = 20 TEST_PROCESS = 20
TEST_PROCESS_RE = 30 TEST_PROCESS_RE = 30
TEST_COMB = 36 TEST_COMB = 36
@ -55,11 +56,12 @@ class TestRecord(CommonADModel):
(TEST_PROCESS, '工序检验'), (TEST_PROCESS, '工序检验'),
(TEST_PROCESS_RE, '工序复检'), (TEST_PROCESS_RE, '工序复检'),
(TEST_COMB, '夹层检验'), (TEST_COMB, '夹层检验'),
(TEST_FINAL, '成品检验') (TEST_FINAL, '成品检验'),
(TEST_FIRST, '首件检验')
) )
form = models.ForeignKey('mtm.recordform', verbose_name='所用表格', on_delete=models.CASCADE) form = models.ForeignKey('mtm.recordform', verbose_name='所用表格', on_delete=models.CASCADE)
type = models.PositiveSmallIntegerField(choices=type_choice, default=TEST_PROCESS) type = models.PositiveSmallIntegerField(choices=type_choice, default=TEST_PROCESS)
is_testok = models.BooleanField('是否合格', default=True) is_testok = models.BooleanField('是否合格', null=True, blank=True)
number = models.CharField('产品编号', null=True, blank=True, max_length=50) number = models.CharField('产品编号', null=True, blank=True, max_length=50)
wproduct = models.ForeignKey('wpm.wproduct', verbose_name='关联的动态产品', on_delete=models.CASCADE, null=True, blank=True, related_name='test_wproduct') wproduct = models.ForeignKey('wpm.wproduct', verbose_name='关联的动态产品', on_delete=models.CASCADE, null=True, blank=True, related_name='test_wproduct')
material = models.ForeignKey('mtm.material', verbose_name='关联的物料状态', on_delete=models.CASCADE, null=True, blank=True) material = models.ForeignKey('mtm.material', verbose_name='关联的物料状态', on_delete=models.CASCADE, null=True, blank=True)

View File

@ -64,6 +64,10 @@ class TestRecordItemSerializer(serializers.ModelSerializer):
model = TestRecordItem model = TestRecordItem
fields = '__all__' fields = '__all__'
class TestRecordShortSerializer(serializers.ModelSerializer):
class Meta:
model = TestRecord
fields = ['id', 'form', 'is_testok', 'is_submited']
class TestRecordCreateSerializer(serializers.ModelSerializer): class TestRecordCreateSerializer(serializers.ModelSerializer):
record_data = TestRecordItemCreateSerializer(many=True) record_data = TestRecordItemCreateSerializer(many=True)
class Meta: class Meta:

View File

@ -93,7 +93,8 @@ class TestRecordViewSet(ListModelMixin, UpdateModelMixin, RetrieveModelMixin, De
with transaction.atomic(): with transaction.atomic():
obj.is_submited=True obj.is_submited=True
obj.save() obj.save()
WpmService.update_wproduct_by_test(obj, request.user) # 这里已经做了日志记录和进度计算 if obj.wproduct:
WpmService.update_wproduct_by_test(obj, request.user) # 这里已经做了日志记录和进度计算
return Response() return Response()
# def create(self, request, *args, **kwargs): # def create(self, request, *args, **kwargs):

View File

@ -90,7 +90,7 @@ class WorkflowViewSet(CreateUpdateModelAMixin, ModelViewSet):
class StateViewSet(CreateModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin, GenericViewSet): class StateViewSet(CreateModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin, GenericViewSet):
perms_map = {'get':'*', 'post':'workflow_update', perms_map = {'get':'*', 'post':'workflow_update',
'put':'workflow_update', 'delete':'workflow_delete'} 'put':'workflow_update', 'delete':'workflow_update'}
queryset = State.objects.all() queryset = State.objects.all()
serializer_class = StateSerializer serializer_class = StateSerializer
search_fields = ['name'] search_fields = ['name']
@ -99,7 +99,7 @@ class StateViewSet(CreateModelMixin, UpdateModelMixin, RetrieveModelMixin, Destr
class TransitionViewSet(CreateModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin, GenericViewSet): class TransitionViewSet(CreateModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin, GenericViewSet):
perms_map = {'get':'*', 'post':'workflow_update', perms_map = {'get':'*', 'post':'workflow_update',
'put':'workflow_update', 'delete':'workflow_delete'} 'put':'workflow_update', 'delete':'workflow_update'}
queryset = Transition.objects.all() queryset = Transition.objects.all()
serializer_class = TransitionSerializer serializer_class = TransitionSerializer
search_fields = ['name'] search_fields = ['name']
@ -108,7 +108,7 @@ class TransitionViewSet(CreateModelMixin, UpdateModelMixin, RetrieveModelMixin,
class CustomFieldViewSet(CreateModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin, GenericViewSet): class CustomFieldViewSet(CreateModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin, GenericViewSet):
perms_map = {'get':'*', 'post':'workflow_update', perms_map = {'get':'*', 'post':'workflow_update',
'put':'workflow_update', 'delete':'workflow_delete'} 'put':'workflow_update', 'delete':'workflow_update'}
queryset = CustomField.objects.all() queryset = CustomField.objects.all()
serializer_class = CustomFieldSerializer serializer_class = CustomFieldSerializer
search_fields = ['field_name'] search_fields = ['field_name']

View File

@ -62,7 +62,7 @@ class FitJSONRenderer(JSONRenderer):
if isinstance(data, list): if isinstance(data, list):
data = data[0] data = data[0]
response_body.msg = prefix + ":" + str(data) # 取一部分放入msg,方便前端alert response_body.msg = prefix + str(data) # 取一部分放入msg,方便前端alert
else: else:
response_body.data = data response_body.data = data
renderer_context.get("response").status_code = 200 # 统一成200响应, 可用body里code区分业务异常 renderer_context.get("response").status_code = 200 # 统一成200响应, 可用body里code区分业务异常