Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop
This commit is contained in:
commit
6e4914b6c8
|
|
@ -60,4 +60,7 @@ export default {
|
||||||
#customerForm .el-form-item{
|
#customerForm .el-form-item{
|
||||||
margin-bottom: 30px!important;
|
margin-bottom: 30px!important;
|
||||||
}
|
}
|
||||||
|
.overFlowShow .el-tabs__content{
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -240,3 +240,10 @@ export function getCodes() {
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
//工单详情
|
||||||
|
export function getWorkflowInit(id) {
|
||||||
|
return request({
|
||||||
|
url: `/wf/workflow/${id}/init/`,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,19 @@
|
||||||
@expand-change="handlerExpand"
|
@expand-change="handlerExpand"
|
||||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||||
>
|
>
|
||||||
<el-table-column label="名称">
|
<el-table-column label="任务编号">
|
||||||
<template slot-scope="scope">{{ scope.row.name }}</template>
|
<template slot-scope="scope">{{ scope.row.name }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="进度">
|
<el-table-column label="产品名称">
|
||||||
<template slot-scope="scope">{{ scope.row.name }}</template>
|
<template slot-scope="scope">
|
||||||
|
<div style="overflow: hidden; text-overflow:ellipsis; white-space: nowrap;">{{ scope.row.productName }}</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="产品型号">
|
||||||
|
<template slot-scope="scope">{{ scope.row.productNum }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="生产数量">
|
||||||
|
<template slot-scope="scope">{{ scope.row.per }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -44,19 +52,12 @@ export default {
|
||||||
BGScrollTop: {
|
BGScrollTop: {
|
||||||
handler: function(newValue) {
|
handler: function(newValue) {
|
||||||
let table = this.$refs.tableMenu.bodyWrapper;
|
let table = this.$refs.tableMenu.bodyWrapper;
|
||||||
// console.log(newValue, table);
|
|
||||||
table.scrollTo(0, newValue);
|
table.scrollTo(0, newValue);
|
||||||
// table.scrollTo({
|
|
||||||
// top: newValue,
|
|
||||||
// left: 0,
|
|
||||||
// behavior: "smooth"
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// tableData: [],
|
|
||||||
checkList: [],
|
checkList: [],
|
||||||
isShowHeaderBox: false,
|
isShowHeaderBox: false,
|
||||||
menuOpen: false,
|
menuOpen: false,
|
||||||
|
|
@ -68,7 +69,6 @@ export default {
|
||||||
handlerWatchScroll() {
|
handlerWatchScroll() {
|
||||||
let table = this.$refs.tableMenu.bodyWrapper;
|
let table = this.$refs.tableMenu.bodyWrapper;
|
||||||
table.addEventListener("scroll", e => {
|
table.addEventListener("scroll", e => {
|
||||||
// console.log(e.srcElement.scrollTop);
|
|
||||||
this.$emit("TableScrollTop", e.srcElement.scrollTop);
|
this.$emit("TableScrollTop", e.srcElement.scrollTop);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-row style="position: fixed;z-index: 2000;top: 465px;right: 10px;">
|
<el-row style="position: absolute;z-index: 2000;top: -38px;right: 150px;display: flex">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="timeRange"
|
v-model="timeRange"
|
||||||
type="monthrange"
|
type="monthrange"
|
||||||
|
|
@ -11,8 +11,30 @@
|
||||||
value-format="yyyy-MM"
|
value-format="yyyy-MM"
|
||||||
@change="timeRangeChange"
|
@change="timeRangeChange"
|
||||||
>
|
>
|
||||||
<!--test-->
|
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
|
<div
|
||||||
|
class="toolTip"
|
||||||
|
style="width: 60px;height: 35px;padding-left: 10px; background: white;margin-left: 10px;border: 1px solid #DCDFE6;line-height: 35px;border-radius: 4px"
|
||||||
|
>
|
||||||
|
<el-dropdown trigger="click">
|
||||||
|
<span class="base">
|
||||||
|
{{currentDaySize.label}}
|
||||||
|
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||||
|
</span>
|
||||||
|
<el-dropdown-menu
|
||||||
|
slot="dropdown"
|
||||||
|
:style="{ left: this.left + 'px !important' }"
|
||||||
|
>
|
||||||
|
<el-dropdown-item
|
||||||
|
v-for="item in currentDaySizeOptions"
|
||||||
|
:key="item.value + 'ee'"
|
||||||
|
@click.native="handleSetDaySize(item)"
|
||||||
|
>
|
||||||
|
{{ item.label }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
<div class="left" style=" width: 400px ;float: left;border-right: 1px solid #f7f7f7">
|
<div class="left" style=" width: 400px ;float: left;border-right: 1px solid #f7f7f7">
|
||||||
<leftMenu
|
<leftMenu
|
||||||
|
|
@ -33,24 +55,6 @@
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="chart" ref="chart">
|
<div class="chart" ref="chart">
|
||||||
<!--<div class="left" :style="{ width: rightLineX + 'px' }">
|
|
||||||
<leftMenu
|
|
||||||
:list="list"
|
|
||||||
ref="leftMenu"
|
|
||||||
:BGScrollTop.sync="BGScrollTop"
|
|
||||||
@TableScrollTop="TableScrollTop"
|
|
||||||
@handlerRowClick="handlerRowClick"
|
|
||||||
@handlerGroup="handlerGroup"
|
|
||||||
@handlerExpand="handlerExpand"
|
|
||||||
></leftMenu>
|
|
||||||
<div class="rightLine" :style="{ left: rightLineX + 'px' }"></div>
|
|
||||||
<div
|
|
||||||
class="rightLine"
|
|
||||||
:style="{ left: rightLineX + 'px' }"
|
|
||||||
ref="rightLine"
|
|
||||||
@mousedown="rightLineMousedown"
|
|
||||||
></div>
|
|
||||||
</div>-->
|
|
||||||
<div class="date">
|
<div class="date">
|
||||||
<div class="years" v-for="item in allDays" :key="item.year">
|
<div class="years" v-for="item in allDays" :key="item.year">
|
||||||
<div
|
<div
|
||||||
|
|
@ -197,14 +201,6 @@
|
||||||
width: item.widthMe + 'px',
|
width: item.widthMe + 'px',
|
||||||
top: item.top + 'px'
|
top: item.top + 'px'
|
||||||
}"
|
}"
|
||||||
@mouseover="
|
|
||||||
lineMouseover(
|
|
||||||
`line${item.id}`,
|
|
||||||
$event,
|
|
||||||
item.id,
|
|
||||||
item.parentId,
|
|
||||||
index
|
|
||||||
)"
|
|
||||||
@mouseleave="lineMouseleave"
|
@mouseleave="lineMouseleave"
|
||||||
@mouseenter="
|
@mouseenter="
|
||||||
lineMouseenter(
|
lineMouseenter(
|
||||||
|
|
@ -241,27 +237,7 @@
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="toolTip">
|
|
||||||
<!--<div class="today base" @click="handleGoToday">今天</div>-->
|
|
||||||
<el-dropdown trigger="click">
|
|
||||||
<span class="base">
|
|
||||||
{{currentDaySize.label}}
|
|
||||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
|
||||||
</span>
|
|
||||||
<el-dropdown-menu
|
|
||||||
slot="dropdown"
|
|
||||||
:style="{ left: this.left + 'px !important' }"
|
|
||||||
>
|
|
||||||
<el-dropdown-item
|
|
||||||
v-for="item in currentDaySizeOptions"
|
|
||||||
:key="item.value + 'ee'"
|
|
||||||
@click.native="handleSetDaySize(item)"
|
|
||||||
>
|
|
||||||
{{ item.label }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</el-dropdown>
|
|
||||||
</div>
|
|
||||||
<transition name="el-zoom-in-center">
|
<transition name="el-zoom-in-center">
|
||||||
<div
|
<div
|
||||||
v-show="isShowMsg"
|
v-show="isShowMsg"
|
||||||
|
|
@ -319,6 +295,8 @@
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
windowWidth:0,
|
||||||
|
windowHeight:0,
|
||||||
leftYear:2021,
|
leftYear:2021,
|
||||||
timeRange: [],
|
timeRange: [],
|
||||||
disable: true,
|
disable: true,
|
||||||
|
|
@ -390,6 +368,13 @@
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted(){
|
mounted(){
|
||||||
|
if(window.innerHeight){
|
||||||
|
this.windowWidth = window.innerWidth;
|
||||||
|
this.windowHeight = window.innerHeight;
|
||||||
|
}else{
|
||||||
|
this.windowHeight=document.body.clientHeight?document.body.clientHeight:document.documentElement.clientHeight;
|
||||||
|
this.windowWidth=document.body.clientWidth?document.body.clientWidth:document.documentElement.clientWidth;
|
||||||
|
}
|
||||||
let currentYear = new Date().getFullYear();
|
let currentYear = new Date().getFullYear();
|
||||||
this.timeRange = [currentYear+'-01',currentYear+'-12'];
|
this.timeRange = [currentYear+'-01',currentYear+'-12'];
|
||||||
this.list = [...this.proList];
|
this.list = [...this.proList];
|
||||||
|
|
@ -534,10 +519,8 @@
|
||||||
},
|
},
|
||||||
//修改后续高度
|
//修改后续高度
|
||||||
resetTop(zindex, reduce, isexpand) {
|
resetTop(zindex, reduce, isexpand) {
|
||||||
// console.log(zindex, reduce, isexpand);
|
|
||||||
let num = reduce ? -40 : 40;
|
let num = reduce ? -40 : 40;
|
||||||
if (!reduce && !isexpand) {
|
if (!reduce && !isexpand) {
|
||||||
// console.log(2);
|
|
||||||
this.list.forEach((item, index) => {
|
this.list.forEach((item, index) => {
|
||||||
if (index > zindex) {
|
if (index > zindex) {
|
||||||
item.top = item.top + 40;
|
item.top = item.top + 40;
|
||||||
|
|
@ -549,7 +532,6 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// console.log(1);
|
|
||||||
this.list.forEach((item, index) => {
|
this.list.forEach((item, index) => {
|
||||||
if (index > zindex) {
|
if (index > zindex) {
|
||||||
item.top = item.top + num * this.list[zindex].children.length;
|
item.top = item.top + num * this.list[zindex].children.length;
|
||||||
|
|
@ -600,7 +582,6 @@
|
||||||
let widthMe = width - left;
|
let widthMe = width - left;
|
||||||
parent.widthMe = parent.widthChild = widthMe;
|
parent.widthMe = parent.widthChild = widthMe;
|
||||||
parent.left = left;
|
parent.left = left;
|
||||||
// return parent;
|
|
||||||
},
|
},
|
||||||
// 转为分组
|
// 转为分组
|
||||||
handlerGroup(row) {
|
handlerGroup(row) {
|
||||||
|
|
@ -674,10 +655,8 @@
|
||||||
let index = this.list.findIndex(k => {
|
let index = this.list.findIndex(k => {
|
||||||
return k.id == parentId;
|
return k.id == parentId;
|
||||||
});
|
});
|
||||||
// console.log(parentId);
|
|
||||||
this.list.forEach(item => {
|
this.list.forEach(item => {
|
||||||
if (item.id == parentId) {
|
if (item.id == parentId) {
|
||||||
// console.log(item, this.list);
|
|
||||||
item.children.forEach(k => {
|
item.children.forEach(k => {
|
||||||
if (k.id == id) {
|
if (k.id == id) {
|
||||||
k.per = per;
|
k.per = per;
|
||||||
|
|
@ -829,6 +808,17 @@
|
||||||
Math.round(end / this.currentDaySize.value) *
|
Math.round(end / this.currentDaySize.value) *
|
||||||
this.currentDaySize.value -
|
this.currentDaySize.value -
|
||||||
this.currentDaySize.value;
|
this.currentDaySize.value;
|
||||||
|
let infoDomX=0,infoDomY = 0;
|
||||||
|
if(this.windowWidth-e.clientX>230){
|
||||||
|
infoDomX = e.clientX;
|
||||||
|
}else{
|
||||||
|
infoDomX = this.windowWidth-230;
|
||||||
|
}
|
||||||
|
if(this.windowHeight-e.clientY>200){
|
||||||
|
infoDomY = e.clientY;
|
||||||
|
}else{
|
||||||
|
infoDomY = this.windowHeight-200;
|
||||||
|
}
|
||||||
this.currentProjectMsg = {
|
this.currentProjectMsg = {
|
||||||
name: this.computedList[index].name,
|
name: this.computedList[index].name,
|
||||||
allTime: (end - start) / this.currentDaySize.value + 1,
|
allTime: (end - start) / this.currentDaySize.value + 1,
|
||||||
|
|
@ -836,8 +826,8 @@
|
||||||
per1: this.computedList[index].per1,
|
per1: this.computedList[index].per1,
|
||||||
startTime: this.computedWithTime(start),
|
startTime: this.computedWithTime(start),
|
||||||
endTime: this.computedWithTime(end),
|
endTime: this.computedWithTime(end),
|
||||||
left: e.clientX,
|
left:infoDomX ,
|
||||||
top: e.clientY + 20
|
top: infoDomY
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
* left:
|
* left:
|
||||||
|
|
@ -864,7 +854,6 @@
|
||||||
left: 0,
|
left: 0,
|
||||||
top: 0
|
top: 0
|
||||||
};
|
};
|
||||||
// this.handlerSelect();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.currentLineDay = {
|
this.currentLineDay = {
|
||||||
|
|
@ -1045,7 +1034,6 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
window.removeEventListener("scroll", this.handleScroll);
|
window.removeEventListener("scroll", this.handleScroll);
|
||||||
document.onmousemove = document.onmouseup = null;
|
document.onmousemove = document.onmouseup = null;
|
||||||
|
|
@ -1055,7 +1043,7 @@
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.chart {
|
.chart {
|
||||||
height: 40vh;
|
height: 280px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
@ -1123,6 +1111,7 @@
|
||||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid #ebeef5;
|
border: 1px solid #ebeef5;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
.lineMsg {
|
.lineMsg {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
|
@ -1165,10 +1154,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolTip {
|
.toolTip {
|
||||||
position: fixed;
|
|
||||||
right: 0;
|
|
||||||
top: 550px;
|
|
||||||
z-index: 999;
|
|
||||||
|
|
||||||
.base {
|
.base {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
|
||||||
|
|
@ -687,9 +687,17 @@
|
||||||
that.field = []; //检查项目
|
that.field = []; //检查项目
|
||||||
let submit = isSubmit=='1'?false:true;
|
let submit = isSubmit=='1'?false:true;
|
||||||
that.formData.forEach((item) => {
|
that.formData.forEach((item) => {
|
||||||
|
let field_value = null;
|
||||||
|
if(item.field_type==='int'){
|
||||||
|
field_value = parseInt(that.checkForm[item.field_key])
|
||||||
|
}else if(item.field_type==='float'){
|
||||||
|
field_value = parseFloat(that.checkForm[item.field_key])
|
||||||
|
}else{
|
||||||
|
field_value = that.checkForm[item.field_key];
|
||||||
|
}
|
||||||
that.field.push({
|
that.field.push({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
field_value: that.checkForm[item.field_key],
|
field_value: field_value,
|
||||||
is_testok: item.is_testok,//单项检查结果
|
is_testok: item.is_testok,//单项检查结果
|
||||||
is_hidden: item.is_hidden
|
is_hidden: item.is_hidden
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -788,9 +788,15 @@
|
||||||
that.field = []; //检查项目
|
that.field = []; //检查项目
|
||||||
let submit = isSubmit=='1'?false:true;
|
let submit = isSubmit=='1'?false:true;
|
||||||
that.formData.forEach((item) => {
|
that.formData.forEach((item) => {
|
||||||
|
let field_value = 0;
|
||||||
|
if(item.field_type==='int'){
|
||||||
|
field_value = parseInt(that.checkForm[item.field_key])
|
||||||
|
}else if(item.field_type==='float'){
|
||||||
|
field_value = parseFloat(that.checkForm[item.field_key])
|
||||||
|
}
|
||||||
that.field.push({
|
that.field.push({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
field_value: that.checkForm[item.field_key],
|
field_value: field_value,
|
||||||
is_testok: item.is_testok,//单项检查结果
|
is_testok: item.is_testok,//单项检查结果
|
||||||
is_hidden: item.is_hidden
|
is_hidden: item.is_hidden
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -185,14 +185,6 @@ export const asyncRoutes = [
|
||||||
component: () => import('@/views/pm/management'),
|
component: () => import('@/views/pm/management'),
|
||||||
meta: { title: '生产任务管理', icon: 'example', perms: ['pm_resources'] }
|
meta: { title: '生产任务管理', icon: 'example', perms: ['pm_resources'] }
|
||||||
}
|
}
|
||||||
,
|
|
||||||
{
|
|
||||||
path: 'gantt',
|
|
||||||
name: 'gantt',
|
|
||||||
component: () => import('@/views/pm/gantt'),
|
|
||||||
meta: { title: '甘特图', icon: 'example',perms: ['vendor_manage'] },
|
|
||||||
// hidden: true
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
|
|
|
||||||
|
|
@ -300,6 +300,8 @@
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
windowWidth:0,
|
||||||
|
windowHeight:0,
|
||||||
timeRange:[],
|
timeRange:[],
|
||||||
disable: true,
|
disable: true,
|
||||||
//当前项是否是子集
|
//当前项是否是子集
|
||||||
|
|
@ -499,11 +501,6 @@
|
||||||
TableScrollTop(val) {
|
TableScrollTop(val) {
|
||||||
let lineBG = this.$refs.lineBG;
|
let lineBG = this.$refs.lineBG;
|
||||||
lineBG.scrollTo(0, val);
|
lineBG.scrollTo(0, val);
|
||||||
// lineBG.scrollTo({
|
|
||||||
// top: val,
|
|
||||||
// left: 0,
|
|
||||||
// behavior: "smooth"
|
|
||||||
// });
|
|
||||||
},
|
},
|
||||||
handlerBGScroll(e) {
|
handlerBGScroll(e) {
|
||||||
this.BGScrollTop = this.$refs.chart.scrollTop;
|
this.BGScrollTop = this.$refs.chart.scrollTop;
|
||||||
|
|
@ -862,15 +859,9 @@
|
||||||
) *
|
) *
|
||||||
this.currentDaySize.value +
|
this.currentDaySize.value +
|
||||||
this.currentDaySize.value;
|
this.currentDaySize.value;
|
||||||
let end =
|
let end = parseInt(this.$refs[dom][0].style.left) + parseInt(this.$refs[dom][0].style.width);
|
||||||
parseInt(this.$refs[dom][0].style.left) +
|
end = Math.round(end / this.currentDaySize.value) * this.currentDaySize.value;
|
||||||
parseInt(this.$refs[dom][0].style.width);
|
this.currentLineDay = { start, end };
|
||||||
end =
|
|
||||||
Math.round(end / this.currentDaySize.value) * this.currentDaySize.value;
|
|
||||||
this.currentLineDay = {
|
|
||||||
start,
|
|
||||||
end
|
|
||||||
};
|
|
||||||
this.isHover = true;
|
this.isHover = true;
|
||||||
this.handlerSelect(this.computedList[index]);
|
this.handlerSelect(this.computedList[index]);
|
||||||
this.lineMouseenter(dom, e, id, parentId, index);
|
this.lineMouseenter(dom, e, id, parentId, index);
|
||||||
|
|
@ -888,13 +879,21 @@
|
||||||
Math.round(
|
Math.round(
|
||||||
parseInt(this.$refs[dom][0].style.left) / this.currentDaySize.value
|
parseInt(this.$refs[dom][0].style.left) / this.currentDaySize.value
|
||||||
) * this.currentDaySize.value;
|
) * this.currentDaySize.value;
|
||||||
let end =
|
let end = parseInt(this.$refs[dom][0].style.left) + parseInt(this.$refs[dom][0].style.width);
|
||||||
parseInt(this.$refs[dom][0].style.left) +
|
end = Math.round(end / this.currentDaySize.value) * this.currentDaySize.value - this.currentDaySize.value;
|
||||||
parseInt(this.$refs[dom][0].style.width);
|
debugger;
|
||||||
end =
|
let infoDomX=0,infoDomY = 0;
|
||||||
Math.round(end / this.currentDaySize.value) *
|
if(this.windowWidth-e.clientX>230){
|
||||||
this.currentDaySize.value -
|
infoDomX = e.clientX;
|
||||||
this.currentDaySize.value;
|
}else{
|
||||||
|
infoDomX = this.windowWidth-230;
|
||||||
|
}
|
||||||
|
if(this.windowHeight-e.clientY>200){
|
||||||
|
infoDomY = e.clientY;
|
||||||
|
}else{
|
||||||
|
infoDomY = this.windowHeight-200;
|
||||||
|
}
|
||||||
|
// if(){}else{}
|
||||||
this.currentProjectMsg = {
|
this.currentProjectMsg = {
|
||||||
name: this.computedList[index].name,
|
name: this.computedList[index].name,
|
||||||
allTime: (end - start) / this.currentDaySize.value + 1,
|
allTime: (end - start) / this.currentDaySize.value + 1,
|
||||||
|
|
@ -902,8 +901,8 @@
|
||||||
per1: this.computedList[index].per1,
|
per1: this.computedList[index].per1,
|
||||||
startTime: this.computedWithTime(start),
|
startTime: this.computedWithTime(start),
|
||||||
endTime: this.computedWithTime(end),
|
endTime: this.computedWithTime(end),
|
||||||
left: e.clientX ,
|
left:infoDomX ,
|
||||||
top: e.clientY + 20
|
top: infoDomY
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
* left:
|
* left:
|
||||||
|
|
@ -1095,6 +1094,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
detailInfo(e,data) {
|
||||||
|
showDiv.style.left = (event.pageX - 300) + 'px';
|
||||||
|
showDiv.style.top = (event.pageY - 120) + 'px';
|
||||||
|
},
|
||||||
currentDaySize(newValue, oldValue) {
|
currentDaySize(newValue, oldValue) {
|
||||||
this.list.forEach(item => {
|
this.list.forEach(item => {
|
||||||
item.left = (item.left / oldValue.value) * newValue.value;
|
item.left = (item.left / oldValue.value) * newValue.value;
|
||||||
|
|
@ -1111,6 +1114,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
if(window.innerHeight){
|
||||||
|
this.windowWidth = window.innerWidth;
|
||||||
|
this.windowHeight = window.innerHeight;
|
||||||
|
}else{
|
||||||
|
this.windowHeight=document.body.clientHeight?document.body.clientHeight:document.documentElement.clientHeight;
|
||||||
|
this.windowWidth=document.body.clientWidth?document.body.clientWidth:document.documentElement.clientWidth;
|
||||||
|
}
|
||||||
document.addEventListener("scroll", this.handleScroll);
|
document.addEventListener("scroll", this.handleScroll);
|
||||||
this.getDay();
|
this.getDay();
|
||||||
this.setStoneLine();
|
this.setStoneLine();
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,7 @@
|
||||||
fit
|
fit
|
||||||
stripe
|
stripe
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
height="100"
|
height="300"
|
||||||
v-el-height-adaptive-table="{ bottomOffset: 40 }"
|
|
||||||
>
|
>
|
||||||
<el-table-column type="index" width="50" />
|
<el-table-column type="index" width="50" />
|
||||||
|
|
||||||
|
|
@ -103,10 +102,14 @@
|
||||||
:limit.sync="listQuery.page_size"
|
:limit.sync="listQuery.page_size"
|
||||||
@pagination="getplanList"
|
@pagination="getplanList"
|
||||||
/>
|
/>
|
||||||
<gantt
|
</el-card>
|
||||||
v-if="ganttShow"
|
<el-card class="box-card">
|
||||||
:proList="proList"
|
<div style="height: 40px;line-height: 40px;background: #F5F7FA;padding-left: 20px;">甘特图</div>
|
||||||
></gantt>
|
<gantt
|
||||||
|
style="position: relative"
|
||||||
|
v-if="proList.length>0"
|
||||||
|
:proList="proList"
|
||||||
|
></gantt>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -138,6 +141,7 @@ export default {
|
||||||
|
|
||||||
listLoading: true,
|
listLoading: true,
|
||||||
proList: [],
|
proList: [],
|
||||||
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {},
|
||||||
|
|
@ -183,9 +187,12 @@ export default {
|
||||||
obj.planTime = [startTime, endTime];
|
obj.planTime = [startTime, endTime];
|
||||||
obj.per = item.count;
|
obj.per = item.count;
|
||||||
obj.type = 1;
|
obj.type = 1;
|
||||||
|
obj.productName = item.product_.name;
|
||||||
|
obj.productNum = item.product_.specification;
|
||||||
obj.isShow = true;
|
obj.isShow = true;
|
||||||
arr.push(obj);
|
arr.push(obj);
|
||||||
}
|
}
|
||||||
|
debugger;
|
||||||
that.proList = arr;
|
that.proList = arr;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@
|
||||||
@pagination="getplanList"
|
@pagination="getplanList"
|
||||||
/>
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-tabs type="border-card" v-model="activeName" @tab-click="activeNameClick">
|
<el-tabs class="overFlowShow" type="border-card" v-model="activeName" @tab-click="activeNameClick">
|
||||||
<el-tab-pane label="订单排产" name="订单排产">
|
<el-tab-pane label="订单排产" name="订单排产">
|
||||||
<el-table
|
<el-table
|
||||||
:data="orderList.results"
|
:data="orderList.results"
|
||||||
|
|
@ -293,6 +293,8 @@
|
||||||
obj.planTime = [startTime, endTime];
|
obj.planTime = [startTime, endTime];
|
||||||
obj.per = item.count;
|
obj.per = item.count;
|
||||||
obj.type = 1;
|
obj.type = 1;
|
||||||
|
obj.productName = item.product_.name;
|
||||||
|
obj.productNum = item.product_.specification;
|
||||||
obj.isShow = true;
|
obj.isShow = true;
|
||||||
arr.push(obj);
|
arr.push(obj);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-card>
|
<el-card>
|
||||||
|
<div style="margin-top: 2px">
|
||||||
<div style="margin-top: 2px">
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
>新增
|
||||||
>新增</el-button
|
</el-button>
|
||||||
>
|
</div>
|
||||||
</div>
|
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 2px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
|
|
@ -14,23 +13,23 @@
|
||||||
:data="customfieldList"
|
:data="customfieldList"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
>
|
>
|
||||||
<el-table-column type="index" width="50" />
|
<el-table-column type="index" width="50"/>
|
||||||
<el-table-column label="字段标识">
|
<el-table-column label="字段标识">
|
||||||
<template slot-scope="scope">{{ scope.row.field_key }}</template>
|
<template slot-scope="scope">{{ scope.row.field_key }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="字段名称">
|
<el-table-column label="字段名称">
|
||||||
<template slot-scope="scope">{{ scope.row.field_name }}</template>
|
<template slot-scope="scope">{{ scope.row.field_name }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="字段类型">
|
<el-table-column label="字段类型">
|
||||||
<template slot-scope="scope">{{ scope.row.field_type }}</template>
|
<template slot-scope="scope">{{ scope.row.field_type }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="顺序ID">
|
<el-table-column label="顺序ID">
|
||||||
<template slot-scope="scope">{{ scope.row.sort }}</template>
|
<template slot-scope="scope">{{ scope.row.sort }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="字段描述">
|
<el-table-column label="字段描述">
|
||||||
<template slot-scope="scope">{{ scope.row.description }}</template>
|
<template slot-scope="scope">{{ scope.row.description }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="创建时间">
|
<el-table-column label="创建时间">
|
||||||
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
|
|
@ -44,13 +43,15 @@
|
||||||
<el-link
|
<el-link
|
||||||
v-if="checkPermission(['customfield_update'])"
|
v-if="checkPermission(['customfield_update'])"
|
||||||
@click="handleEdit(scope)"
|
@click="handleEdit(scope)"
|
||||||
>编辑</el-link
|
>编辑
|
||||||
|
</el-link
|
||||||
>
|
>
|
||||||
<el-link
|
<el-link
|
||||||
v-if="checkPermission(['customfield_delete'])"
|
v-if="checkPermission(['customfield_delete'])"
|
||||||
type="danger"
|
type="danger"
|
||||||
@click="handleDeleteCustomfield(scope)"
|
@click="handleDeleteCustomfield(scope)"
|
||||||
>删除</el-link
|
>删除
|
||||||
|
</el-link
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -67,18 +68,18 @@
|
||||||
label-position="right"
|
label-position="right"
|
||||||
:rules="rule1">
|
:rules="rule1">
|
||||||
<el-form-item label="字段标识" prop="field_key">
|
<el-form-item label="字段标识" prop="field_key">
|
||||||
<el-input v-model="customfield.field_key" placeholder="字段标识" />
|
<el-input v-model="customfield.field_key" placeholder="字段标识"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="字段名称" prop="field_name">
|
<el-form-item label="字段名称" prop="field_name">
|
||||||
<el-input v-model="customfield.field_name" placeholder="字段名称" />
|
<el-input v-model="customfield.field_name" placeholder="字段名称"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="字段描述" prop="description">
|
<el-form-item label="字段描述" prop="description">
|
||||||
<el-input v-model="customfield.description" placeholder="字段描述" />
|
<el-input v-model="customfield.description" placeholder="字段描述"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="占位符" prop="placeholder">
|
<el-form-item label="占位符" prop="placeholder">
|
||||||
<el-input v-model="customfield.placeholder" placeholder="占位符" />
|
<el-input v-model="customfield.placeholder" placeholder="占位符"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="字段类型" prop="field_type">
|
<el-form-item label="展示标签" prop="field_type">
|
||||||
<el-select style="width: 100%" v-model="customfield.field_type" placeholder="请选择">
|
<el-select style="width: 100%" v-model="customfield.field_type" placeholder="请选择">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in options"
|
v-for="item in options"
|
||||||
|
|
@ -88,28 +89,53 @@
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="字段标签" v-show="customfield.field_type=='select'||customfield.field_type=='selects'">
|
||||||
|
<el-input v-model="customfield.label" placeholder="选项类型"/>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="选项" v-show="customfield.field_type=='select'||customfield.field_type=='selects'">
|
<el-form-item label="选项" v-show="customfield.field_type=='select'||customfield.field_type=='selects'">
|
||||||
<el-button @click.prevent="addDomain" style="border: none;">
|
<el-button @click.prevent="addDomain" style="border: none;">
|
||||||
<i class="el-icon-circle-plus-outline"></i>
|
<i class="el-icon-circle-plus-outline"></i>
|
||||||
<span style="font-size:14px;">添加</span>
|
<span style="font-size:14px;">添加</span>
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-row v-for="(domain, $index) in choiceOption" :key=domain+$index style="margin-bottom: 10px">
|
<el-row v-for="(domain, $index) in choiceOption" :key='$index+1' style="margin-bottom: 10px">
|
||||||
<el-col :span="20">
|
<el-col :span="10">
|
||||||
<el-input v-model="choiceOption[$index]" auto-complete="off"></el-input>
|
<template>
|
||||||
|
<el-form-item label="id:">
|
||||||
|
<el-input type="number" v-model="choiceOption[$index].id" auto-complete="off" placeholder="id为整数"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="10">
|
||||||
|
<template>
|
||||||
|
<el-form-item label="name:">
|
||||||
|
<el-input v-model="choiceOption[$index].name" auto-complete="off"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="3" style="text-align: center" v-if="$index!==0">
|
<el-col :span="3" style="text-align: center" v-if="$index!==0">
|
||||||
<i class="el-icon-remove-outline" @click.prevent="removeDomain($index,'1')" style="color: red;font-size: 16px;"></i>
|
<i
|
||||||
|
class="el-icon-remove-outline"
|
||||||
|
style="color: red;font-size: 16px;"
|
||||||
|
@click.prevent="removeDomain($index,'1')"
|
||||||
|
></i>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="顺序ID" prop="sort">
|
<el-form-item label="顺序ID">
|
||||||
<el-input v-model="customfield.sort" type="number" placeholder="顺序" />
|
<el-input v-model="customfield.sort" type="number" placeholder="顺序"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="默认值" prop="default_value">
|
<el-form-item label="默认值">
|
||||||
<el-input v-model="customfield.default_value" placeholder="默认值" />
|
<el-input v-model="customfield.default_value" placeholder="默认值"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="模板" prop="field_template">
|
<el-form-item label="模板">
|
||||||
<el-input v-model="customfield.field_template" placeholder="你有一个待办工单:{title}" />
|
<el-input v-model="customfield.field_template" placeholder="你有一个待办工单:{title}"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否隐藏">
|
||||||
|
<el-radio-group v-model="customfield.is_hidden">
|
||||||
|
<el-radio :label="false">显示</el-radio>
|
||||||
|
<el-radio :label="true">隐藏</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div style="text-align: right">
|
<div style="text-align: right">
|
||||||
|
|
@ -120,39 +146,53 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { getWfCustomfieldList, createWfCustomfield,updateWfCustomfield,deleteWfCustomfield } from "@/api/workflow";
|
import {getWfCustomfieldList, createWfCustomfield, updateWfCustomfield, deleteWfCustomfield} from "@/api/workflow";
|
||||||
import checkPermission from "@/utils/permission";
|
import checkPermission from "@/utils/permission";
|
||||||
import vueJsonEditor from 'vue-json-editor'
|
import vueJsonEditor from 'vue-json-editor'
|
||||||
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
||||||
const defaultcustomfield = {
|
const defaultcustomfield = {
|
||||||
field_key: "",
|
field_key: "",
|
||||||
field_name: "",
|
field_name: "",
|
||||||
};
|
};
|
||||||
export default {
|
export default {
|
||||||
components: { Pagination,vueJsonEditor },
|
components: {Pagination, vueJsonEditor},
|
||||||
name: "CTF",
|
name: "CTF",
|
||||||
props: ["ID"],
|
props: ["ID"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
customfield: {
|
customfield: {
|
||||||
field_key:'',
|
field_key: '',
|
||||||
field_name:'',
|
field_name: '',
|
||||||
placeholder:'',
|
placeholder: '',
|
||||||
field_type:'',
|
field_type: '',
|
||||||
sort:'',
|
sort: '',
|
||||||
default_value:'',
|
label: 'name',
|
||||||
field_template:'',
|
default_value: '',
|
||||||
field_choice:[]
|
field_template: '',
|
||||||
},
|
field_choice: [],
|
||||||
view_permission_check:false,
|
is_hidden:false,
|
||||||
hasJsonFlag:true, // json是否验证通过
|
},
|
||||||
hasJsonFlag1:true, // json是否验证通过
|
fieldHidden: true,
|
||||||
hasJsonFlag2:true, // json是否验证通过
|
fieldBlock: false,
|
||||||
// customfieldList: {
|
view_permission_check: false,
|
||||||
// count:0
|
hasJsonFlag: true, // json是否验证通过
|
||||||
// },
|
hasJsonFlag1: true, // json是否验证通过
|
||||||
customfieldList:[],
|
hasJsonFlag2: true, // json是否验证通过
|
||||||
options: [{
|
// customfieldList: {
|
||||||
|
// count:0
|
||||||
|
// },
|
||||||
|
customfieldList: [''],
|
||||||
|
labels:[{
|
||||||
|
label: '常规',
|
||||||
|
value: 'name'
|
||||||
|
},{
|
||||||
|
label: '名称|id',
|
||||||
|
value: 'name|id'
|
||||||
|
},{
|
||||||
|
label: '人员选择',
|
||||||
|
value: 'user'
|
||||||
|
}],
|
||||||
|
options: [{
|
||||||
value: 'string',
|
value: 'string',
|
||||||
label: '文本'
|
label: '文本'
|
||||||
}, {
|
}, {
|
||||||
|
|
@ -167,172 +207,176 @@ export default {
|
||||||
}, {
|
}, {
|
||||||
value: 'datetime',
|
value: 'datetime',
|
||||||
label: '日期时间'
|
label: '日期时间'
|
||||||
},{
|
}, {
|
||||||
value: 'select',
|
value: 'select',
|
||||||
label: '单选'
|
label: '单选'
|
||||||
},{
|
}, {
|
||||||
value: 'selects',
|
value: 'selects',
|
||||||
label: '多选'
|
label: '多选'
|
||||||
}, {
|
}, {
|
||||||
value: 'textarea',
|
value: 'textarea',
|
||||||
label: '文本域'
|
label: '文本域'
|
||||||
}, {
|
},{
|
||||||
|
value: 'file',
|
||||||
|
label: '附件'
|
||||||
|
}],
|
||||||
|
/*, {
|
||||||
value: 'selectuser',
|
value: 'selectuser',
|
||||||
label: '用户名'
|
label: '用户名'
|
||||||
}, {
|
}, {
|
||||||
value: 'selectusers',
|
value: 'selectusers',
|
||||||
label: '多选的用户名'
|
label: '多选的用户名'
|
||||||
}, {
|
}, */
|
||||||
value: 'file',
|
|
||||||
label: '附件'
|
|
||||||
}],
|
|
||||||
|
|
||||||
|
|
||||||
boolean_field_display:[],
|
boolean_field_display: [],
|
||||||
choiceOption:[''],
|
choiceOption: [{id:null,name:""}],
|
||||||
field_choice:[],
|
field_choice: [],
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
dialogType: "new",
|
dialogType: "new",
|
||||||
rule1: {
|
rule1: {
|
||||||
name: [{ required: true, message: "请输入", trigger: "blur" }],
|
name: [{required: true, message: "请输入", trigger: "blur"}],
|
||||||
description: [{ required: true, message: "请输入", trigger: "blur" }]
|
description: [{required: true, message: "请输入", trigger: "blur"}]
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
watch: {},
|
||||||
|
created() {
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
//添加字段选项
|
||||||
|
addDomain() {
|
||||||
|
this.choiceOption.push({id:null,name:""})
|
||||||
},
|
},
|
||||||
};
|
//删除字段选项
|
||||||
},
|
removeDomain(index) {
|
||||||
computed: {},
|
this.choiceOption.splice(index, 1)
|
||||||
watch: {},
|
},
|
||||||
created() {
|
checkPermission,
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
//添加字段选项
|
|
||||||
addDomain() {
|
|
||||||
this.choiceOption.push('')
|
|
||||||
},
|
|
||||||
//删除字段选项
|
|
||||||
removeDomain(index){
|
|
||||||
this.choiceOption.splice(index, 1)
|
|
||||||
},
|
|
||||||
checkPermission,
|
|
||||||
|
|
||||||
getList() {
|
getList() {
|
||||||
|
getWfCustomfieldList(this.ID).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.customfieldList = response.data;
|
||||||
|
}
|
||||||
|
|
||||||
getWfCustomfieldList(this.ID).then((response) => {
|
|
||||||
if (response.data) {
|
|
||||||
this.customfieldList = response.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
handleFilter() {
|
|
||||||
this.listQuery.page = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
resetFilter() {
|
|
||||||
this.listQuery = {
|
|
||||||
page: 1,
|
|
||||||
page_size: 20,
|
|
||||||
}
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
handleCreate() {
|
|
||||||
this.customfield = Object.assign({}, defaultcustomfield);
|
|
||||||
this.dialogType = "new";
|
|
||||||
this.dialogVisible = true;
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs["Form"].clearValidate();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
handleEdit(scope) {
|
|
||||||
this.customfield = Object.assign({}, scope.row); // copy obj
|
|
||||||
this.choiceOption = scope.row.field_choice;
|
|
||||||
this.dialogType = "edit";
|
|
||||||
this.dialogVisible = true;
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs["Form"].clearValidate();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handlecfgt(scope)
|
|
||||||
{
|
|
||||||
this.$router.push({name:"configuration",params:{customfield:scope.row.id}})
|
|
||||||
}
|
|
||||||
,
|
|
||||||
handleDelete(scope) {
|
|
||||||
this.$confirm("确认删除?", "警告", {
|
|
||||||
confirmButtonText: "确认",
|
|
||||||
cancelButtonText: "取消",
|
|
||||||
type: "error",
|
|
||||||
})
|
|
||||||
.then(async () => {
|
|
||||||
await deleteWorkflow(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();
|
||||||
|
},
|
||||||
|
handleCreate() {
|
||||||
|
this.customfield = Object.assign({}, defaultcustomfield);
|
||||||
|
this.dialogType = "new";
|
||||||
|
this.dialogVisible = true;
|
||||||
|
/*this.$nextTick(() => {
|
||||||
|
// this.$refs["Form"].clearValidate();
|
||||||
|
this.customfield.label = 1;
|
||||||
|
});*/
|
||||||
|
},
|
||||||
|
|
||||||
|
handleEdit(scope) {
|
||||||
|
debugger;
|
||||||
|
this.customfield = Object.assign({}, scope.row); // copy obj
|
||||||
|
this.choiceOption = scope.row.field_choice;
|
||||||
|
this.dialogType = "edit";
|
||||||
|
this.dialogVisible = true;
|
||||||
|
/*this.$nextTick(() => {
|
||||||
|
this.$refs["Form"].clearValidate();
|
||||||
|
});*/
|
||||||
|
},
|
||||||
|
handlecfgt(scope) {
|
||||||
|
this.$router.push({name: "configuration", params: {customfield: scope.row.id}})
|
||||||
|
}
|
||||||
|
,
|
||||||
|
handleDelete(scope) {
|
||||||
|
this.$confirm("确认删除?", "警告", {
|
||||||
|
confirmButtonText: "确认",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
await this.deleteWorkflow(scope.row.id);
|
||||||
|
this.getList();
|
||||||
|
this.$message.success("成功");
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
async confirm(form) {
|
async confirm(form) {
|
||||||
this.$refs[form].validate((valid) => {
|
let that = this,choiceArr = [];
|
||||||
if (valid) {
|
this.$refs[form].validate((valid) => {
|
||||||
const isEdit = this.dialogType === "edit";
|
if (valid) {
|
||||||
if (isEdit) {
|
const isEdit = that.dialogType === "edit";
|
||||||
this.checkJson();
|
if(that.choiceOption[0]&&that.choiceOption[0].name!==''&&that.choiceOption[0].name!==null&&that.choiceOption[0].name!==undefined){
|
||||||
this.checkJson1();
|
that.choiceOption.forEach((item)=>{
|
||||||
this.checkJson2();
|
let obj = new Object();
|
||||||
this.customfield.field_choice = this.choiceOption;
|
obj.id = parseInt(item.id);
|
||||||
updateWfCustomfield(this.customfield.id, this.customfield).then((res) => {
|
obj.name = item.name;
|
||||||
if (res.code >= 200) {
|
choiceArr.push(obj);
|
||||||
this.getList();
|
})
|
||||||
this.dialogVisible = false;
|
}
|
||||||
this.$message.success("成功");
|
debugger;
|
||||||
}
|
console.log(choiceArr);
|
||||||
});
|
that.customfield.field_choice = choiceArr;
|
||||||
|
console.log(that.customfield);
|
||||||
|
if (isEdit) {
|
||||||
|
updateWfCustomfield(this.customfield.id, this.customfield).then((res) => {
|
||||||
|
if (res.code >= 200) {
|
||||||
|
this.getList();
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$message.success("成功");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.customfield.workflow = this.ID;
|
||||||
|
createWfCustomfield(this.customfield).then((res) => {
|
||||||
|
if (res.code >= 200) {
|
||||||
|
this.getList();
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$message.success("成功");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.checkJson();
|
return false;
|
||||||
this.checkJson1();
|
|
||||||
this.checkJson2();
|
|
||||||
this.customfield.workflow=this.ID;
|
|
||||||
this.customfield.field_choice = this.choiceOption;
|
|
||||||
createWfCustomfield(this.customfield).then((res) => {
|
|
||||||
if (res.code >= 200) {
|
|
||||||
this.getList();
|
|
||||||
this.dialogVisible = false;
|
|
||||||
this.$message.success("成功");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleDeleteCustomfield(scope) {
|
|
||||||
this.$confirm("确认删除?", "警告", {
|
|
||||||
confirmButtonText: "确认",
|
|
||||||
cancelButtonText: "取消",
|
|
||||||
type: "error",
|
|
||||||
})
|
|
||||||
.then(async () => {
|
|
||||||
await deleteWfCustomfield(scope.row.id);
|
|
||||||
this.getList();
|
|
||||||
this.$message.success("成功");
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error(err);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
handleDeleteCustomfield(scope) {
|
||||||
|
this.$confirm("确认删除?", "警告", {
|
||||||
|
confirmButtonText: "确认",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
await deleteWfCustomfield(scope.row.id);
|
||||||
|
this.getList();
|
||||||
|
this.$message.success("成功");
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
onJsonChange (value) {
|
/* onJsonChange(value) {
|
||||||
// console.log('更改value:', value);
|
// console.log('更改value:', value);
|
||||||
// 实时保存
|
// 实时保存
|
||||||
this.onJsonSave(value)
|
this.onJsonSave(value)
|
||||||
},
|
},
|
||||||
onJsonSave (value) {
|
onJsonSave(value) {
|
||||||
// console.log('保存value:', value);
|
// console.log('保存value:', value);
|
||||||
this.boolean_field_display = value
|
this.boolean_field_display = value
|
||||||
this.hasJsonFlag = true
|
this.hasJsonFlag = true
|
||||||
|
|
@ -343,61 +387,61 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
// 检查json
|
// 检查json
|
||||||
checkJson(){
|
checkJson() {
|
||||||
if (this.hasJsonFlag == false){
|
if (this.hasJsonFlag == false) {
|
||||||
alert("布尔显示定义json验证失败")
|
// alert("布尔显示定义json验证失败")
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
alert("布尔显示定义json验证成功")
|
// alert("布尔显示定义json验证成功")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onJsonChange1 (value) {
|
onJsonChange1(value) {
|
||||||
// console.log('更改value:', value);
|
// console.log('更改value:', value);
|
||||||
// 实时保存
|
// 实时保存
|
||||||
this.onJsonSave1(value)
|
this.onJsonSave1(value)
|
||||||
},
|
},
|
||||||
onJsonSave1 (value) {
|
onJsonSave1(value) {
|
||||||
this.field_choice = value
|
this.field_choice = value
|
||||||
this.hasJsonFlag1 = true
|
this.hasJsonFlag1 = true
|
||||||
},
|
},
|
||||||
onError1(value) {
|
onError1(value) {
|
||||||
this.hasJsonFlag1 = false
|
this.hasJsonFlag1 = false
|
||||||
},
|
},
|
||||||
// 检查json
|
// 检查json
|
||||||
checkJson1(){
|
checkJson1() {
|
||||||
if (this.hasJsonFlag1 == false){
|
if (this.hasJsonFlag1 == false) {
|
||||||
alert("选项json验证失败")
|
// alert("选项json验证失败")
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
alert("选项json1验证成功")
|
// alert("选项json1验证成功")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onJsonChange2 (value) {
|
onJsonChange2(value) {
|
||||||
// console.log('更改value:', value);
|
// console.log('更改value:', value);
|
||||||
// 实时保存
|
// 实时保存
|
||||||
this.onJsonSave2(value)
|
this.onJsonSave2(value)
|
||||||
},
|
},
|
||||||
onJsonSave2 (value) {
|
onJsonSave2(value) {
|
||||||
this.field_choice = value
|
this.field_choice = value
|
||||||
this.hasJsonFlag2 = true
|
this.hasJsonFlag2 = true
|
||||||
},
|
},
|
||||||
onError2(value) {
|
onError2(value) {
|
||||||
this.hasJsonFlag2 = false
|
this.hasJsonFlag2 = false
|
||||||
},
|
},
|
||||||
// 检查json
|
// 检查json
|
||||||
checkJson2(){
|
checkJson2() {
|
||||||
if (this.hasJsonFlag2 == false){
|
if (this.hasJsonFlag2 == false) {
|
||||||
alert("标签json验证失败")
|
// alert("标签json验证失败")
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
alert("标签json1验证成功")
|
// alert("标签json1验证成功")
|
||||||
return true
|
return true
|
||||||
}
|
}*/
|
||||||
},
|
// },
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -428,20 +428,20 @@ export default {
|
||||||
// 检查json
|
// 检查json
|
||||||
checkJson(){
|
checkJson(){
|
||||||
if (this.hasJsonFlag == false){
|
if (this.hasJsonFlag == false){
|
||||||
alert("限制表达式json验证失败")
|
// alert("限制表达式json验证失败")
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
alert("限制表达式json验证成功")
|
// alert("限制表达式json验证成功")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 检查json
|
// 检查json
|
||||||
checkJson2(){
|
checkJson2(){
|
||||||
if (this.hasJsonFlag1 == false){
|
if (this.hasJsonFlag1 == false){
|
||||||
alert("展现表单字段json验证失败")
|
// alert("展现表单字段json验证失败")
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
alert("展现表单字段json1验证成功")
|
// alert("展现表单字段json1验证成功")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -184,14 +184,20 @@
|
||||||
<el-col :span="1" style="height: 1px;"></el-col>
|
<el-col :span="1" style="height: 1px;"></el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-select style="width: 100%" v-model="item.value" placeholder="请选择状态">
|
<el-select style="width: 100%" v-model="item.value" placeholder="请选择状态">
|
||||||
<el-option label="只读" value="1"></el-option>
|
<el-option
|
||||||
<el-option label="必填" value="2"></el-option>
|
v-for="item in state_fields"
|
||||||
<el-option label="可选" value="3"></el-option>
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
:key="item.value"
|
||||||
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="2" style="text-align: center" v-if="$index!==0">
|
<el-col :span="2" style="text-align: center" v-if="$index!==0">
|
||||||
<i class="el-icon-remove-outline" @click.prevent="removeStatusChange($index)"
|
<i
|
||||||
style="color: red;font-size: 16px;"></i>
|
class="el-icon-remove-outline"
|
||||||
|
style="color: red;font-size: 16px;"
|
||||||
|
@click.prevent="removeStatusChange($index)"
|
||||||
|
></i>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
@ -291,6 +297,21 @@
|
||||||
value: 9,
|
value: 9,
|
||||||
label: '代码获取'
|
label: '代码获取'
|
||||||
}],
|
}],
|
||||||
|
state_fields:[
|
||||||
|
{
|
||||||
|
value: 1,
|
||||||
|
label: '只读'
|
||||||
|
},{
|
||||||
|
value: 2,
|
||||||
|
label: '必填'
|
||||||
|
},{
|
||||||
|
value: 3,
|
||||||
|
label: '可选'
|
||||||
|
},{
|
||||||
|
value: 4,
|
||||||
|
label: '隐藏'
|
||||||
|
},
|
||||||
|
],
|
||||||
display_form_str: [],
|
display_form_str: [],
|
||||||
limit_expression: [],
|
limit_expression: [],
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
|
|
@ -315,8 +336,8 @@
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
checkPermission(value){
|
checkPermission(value){
|
||||||
debugger;
|
/* debugger;
|
||||||
console.log(checkPermission(value))
|
console.log(checkPermission(value))*/
|
||||||
checkPermission(value);
|
checkPermission(value);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -308,9 +308,9 @@
|
||||||
<el-select style="width: 100%" v-model="item.default_value" placeholder="请选择">
|
<el-select style="width: 100%" v-model="item.default_value" placeholder="请选择">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item1 in item.field_choice"
|
v-for="item1 in item.field_choice"
|
||||||
:key="item1"
|
:key="item1.id"
|
||||||
:label="item1"
|
:label="item1.name"
|
||||||
:value="item1"
|
:value="item1.id"
|
||||||
>
|
>
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
@ -319,9 +319,9 @@
|
||||||
<el-select style="width: 100%" multiple v-model="item.default_value" placeholder="请选择">
|
<el-select style="width: 100%" multiple v-model="item.default_value" placeholder="请选择">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item1 in item.field_choice"
|
v-for="item1 in item.field_choice"
|
||||||
:key="item1"
|
:key="item1.id"
|
||||||
:label="item1"
|
:label="item1.name"
|
||||||
:value="item1"
|
:value="item1.id"
|
||||||
>
|
>
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-row style="display: flex;flex-wrap: wrap;width:100%;">
|
<el-row style="display: flex;flex-wrap: wrap;width:100%;">
|
||||||
<el-col v-for="item in ticketDetail.ticket_data_" :key="item.id" :span="12">
|
<el-col v-for="item in ticketDetail.ticket_data_" :key="item.id" :span="12" v-show="!item.is_hidden">
|
||||||
<el-form-item :label="item.field_name" v-if="item.field_state==='1'">
|
<el-form-item :label="item.field_name" v-if="item.field_state==='1'">
|
||||||
<span>{{ticketDetail.ticket_data[item.field_key]}}</span>
|
<span>{{ticketDetail.ticket_data[item.field_key]}}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
@ -73,9 +73,9 @@
|
||||||
<el-select style="width: 100%" v-model="ticketDetail.ticket_data[item.field_key]" placeholder="请选择">
|
<el-select style="width: 100%" v-model="ticketDetail.ticket_data[item.field_key]" placeholder="请选择">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item1 in item.field_choice"
|
v-for="item1 in item.field_choice"
|
||||||
:key="item1"
|
:key="item1.id"
|
||||||
:label="item1"
|
:label="item1.name"
|
||||||
:value="item1"
|
:value="item1.id"
|
||||||
>
|
>
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
@ -84,9 +84,9 @@
|
||||||
<el-select style="width: 100%" multiple v-model="ticketDetail.ticket_data[item.field_key]" placeholder="请选择">
|
<el-select style="width: 100%" multiple v-model="ticketDetail.ticket_data[item.field_key]" placeholder="请选择">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item1 in item.field_choice"
|
v-for="item1 in item.field_choice"
|
||||||
:key="item1"
|
:key="item1.id"
|
||||||
:label="item1"
|
:label="item1.name"
|
||||||
:value="item1"
|
:value="item1.id"
|
||||||
>
|
>
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
@ -132,7 +132,6 @@
|
||||||
<el-button v-if="ticketDetail.in_add_node" class="filter-item" type="primary" @click="handleClick('3')">加签处理</el-button>
|
<el-button v-if="ticketDetail.in_add_node" class="filter-item" type="primary" @click="handleClick('3')">加签处理</el-button>
|
||||||
<el-button v-for="item in operationBtn" :key="item.id" class="filter-item" type="primary" @click="operationSubmit(item.id)">{{item.name}}</el-button>
|
<el-button v-for="item in operationBtn" :key="item.id" class="filter-item" type="primary" @click="operationSubmit(item.id)">{{item.name}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-left: 10px">
|
<el-card style="margin-left: 10px">
|
||||||
|
|
@ -205,6 +204,7 @@
|
||||||
</template>
|
</template>
|
||||||
<script src="https://d3js.org/d3.v4.min.js"></script>
|
<script src="https://d3js.org/d3.v4.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
import { getOrgAll } from "@/api/org";
|
||||||
import { upUrl, upHeaders } from "@/api/file";
|
import { upUrl, upHeaders } from "@/api/file";
|
||||||
import { getUserList } from "@/api/user";
|
import { getUserList } from "@/api/user";
|
||||||
import {getWorkflowList,getWfCustomfieldList,getWfStateList,getWfTransitionList,ticketHandle
|
import {getWorkflowList,getWfCustomfieldList,getWfStateList,getWfTransitionList,ticketHandle
|
||||||
|
|
@ -247,6 +247,7 @@
|
||||||
watchedName:'',
|
watchedName:'',
|
||||||
watchedCreateTime:'',
|
watchedCreateTime:'',
|
||||||
logs:[],
|
logs:[],
|
||||||
|
orgList:[],
|
||||||
staffs:[],
|
staffs:[],
|
||||||
edges: [],
|
edges: [],
|
||||||
nodes: [],
|
nodes: [],
|
||||||
|
|
@ -288,156 +289,189 @@
|
||||||
getTicketTransitions(ticketId).then(res=>{
|
getTicketTransitions(ticketId).then(res=>{
|
||||||
this.operationBtn = res.data;
|
this.operationBtn = res.data;
|
||||||
})
|
})
|
||||||
getWfFlowSteps( ticketId).then((res)=>{
|
getOrgAll().then((orgRes) => {
|
||||||
if(res.data){
|
that.orgList = orgRes.data;
|
||||||
//流程步骤数组
|
getUserList({page:0}).then(userRes=>{
|
||||||
that.flowSteps = res.data;
|
if(userRes.data){
|
||||||
getTicketDetail( ticketId).then((res)=>{
|
that.staffs = userRes.data;
|
||||||
if(res.data){
|
getWfFlowSteps( ticketId).then((res)=>{
|
||||||
that.tooltip = that.createTooltip();
|
if(res.data){
|
||||||
that.ticketDetail = res.data;
|
//流程步骤数组
|
||||||
|
that.flowSteps = res.data;
|
||||||
console.log(that.ticketDetail.state_.enable_retreat);
|
getTicketDetail( ticketId).then((res)=>{
|
||||||
debugger;
|
if(res.data){
|
||||||
let state = res.data.state;
|
that.tooltip = that.createTooltip();
|
||||||
let dat = that.flowSteps.filter((item)=>{
|
that.ticketDetail = res.data;
|
||||||
return item.id==state;
|
for (let i=0;i<that.ticketDetail.ticket_data_.length;i++) {
|
||||||
})
|
if(that.ticketDetail.ticket_data_[i].label==="sys_user"){
|
||||||
that.sort = dat[0].sort;
|
that.ticketDetail.ticket_data_[i].field_choice = that.staffs;
|
||||||
that.actives = that.flowSteps.indexOf(dat[0]);
|
}
|
||||||
if( that.flowSteps.length-that.actives >1){}else{
|
if(that.ticketDetail.ticket_data_[i].label==="deptSelect"){
|
||||||
that.actives =that.flowSteps.length;
|
that.ticketDetail.ticket_data_[i].field_choice = that.orgList;
|
||||||
}
|
}
|
||||||
var g = new dagreD3.graphlib.Graph().setGraph({
|
|
||||||
rankdir: 'DL',
|
|
||||||
nodesep: 100,
|
|
||||||
edgesep: 10,//两条线之间的距离
|
|
||||||
ranksep: 50,//节点之间的距离
|
|
||||||
marginx: 60,
|
|
||||||
marginy: 20,
|
|
||||||
});
|
|
||||||
//获取state得到节点
|
|
||||||
getWfStateList(workflow).then((response) => {
|
|
||||||
if (response.data) {
|
|
||||||
let nodes = response.data;
|
|
||||||
// 添加节点
|
|
||||||
nodes.forEach((item) => {
|
|
||||||
if(item.sort==that.sort){
|
|
||||||
g.setNode(item.id, {
|
|
||||||
// 节点标签
|
|
||||||
label: item.name,
|
|
||||||
// 节点形状
|
|
||||||
shape: 'rect',
|
|
||||||
toolText: item.name,
|
|
||||||
//节点样式
|
|
||||||
style: "fill:#409EFF;stroke:#000",
|
|
||||||
labelStyle: "fill:#000;",
|
|
||||||
rx :5,//矩形节点圆角度
|
|
||||||
ry :5
|
|
||||||
});
|
|
||||||
|
|
||||||
}else{
|
|
||||||
g.setNode(item.id, {
|
|
||||||
// 节点标签
|
|
||||||
label: item.name,
|
|
||||||
// 节点形状
|
|
||||||
shape: 'rect',
|
|
||||||
toolText: item.name,
|
|
||||||
//节点样式
|
|
||||||
style: "fill:#fff;stroke:#000",
|
|
||||||
labelStyle: "fill:#000;",
|
|
||||||
rx :5,//矩形节点圆角度
|
|
||||||
ry :5
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
console.log(that.ticketDetail.state_.enable_retreat);
|
||||||
g.nodes().forEach(function (v) {
|
let state = res.data.state;
|
||||||
console.log("Node " + v + ": " + JSON.stringify(g.node(v)));
|
let dat = that.flowSteps.filter((item)=>{
|
||||||
});
|
return item.id==state;
|
||||||
//获取流转得到线 链接关系
|
})
|
||||||
getWfTransitionList(workflow).then((res)=>{
|
debugger;
|
||||||
if(res.data){
|
let state_fields = dat[0].state_fields;
|
||||||
let transitionList = res.data;
|
if(state_fields!=={}){
|
||||||
transitionList.forEach((transitions)=>{
|
for (let labe in state_fields) {
|
||||||
let transition0 = transitions;
|
for(let j = 0;j<that.ticketDetail.ticket_data_.length;j++){
|
||||||
if (transition0.condition_expression.length>0){
|
if(that.ticketDetail.ticket_data_[j].field_key===labe){
|
||||||
g.setNode(transition0.source_state_.id+100000, {label: "条件表达式", style: "fill: #a4d088", shape: "diamond"});
|
debugger;
|
||||||
g.setEdge(transition0.source_state_.id, transition0.source_state_.id+100000, {
|
console.log(labe)
|
||||||
// 边标签
|
console.log(state_fields[labe])
|
||||||
label: transition0.name,
|
if(state_fields[labe]!==4){
|
||||||
style: "fill:#ffffff;stroke:#c0c1c3;stroke-width:1.5px"
|
that.ticketDetail.ticket_data_[j].is_hidden = false
|
||||||
});
|
}else{
|
||||||
let condition_expression = transition0.condition_expression;
|
that.ticketDetail.ticket_data_[j].is_hidden = true
|
||||||
condition_expression.forEach(condition_expression0=>{
|
}
|
||||||
g.setEdge(transition0.source_state_.id+100000, condition_expression0.target_state, {
|
}
|
||||||
label: condition_expression0.label,
|
|
||||||
style: "fill:#ffffff;stroke:#c0c1c3;stroke-width:1.5px"
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}else{
|
|
||||||
g.setEdge(transition0.source_state_.id, transition0.destination_state_.id, {
|
|
||||||
// 边标签
|
|
||||||
label: transition0.name,
|
|
||||||
// 边样式
|
|
||||||
style: "fill:#ffffff;stroke:#c0c1c3;stroke-width:1.5px" // 根据后台数据来改变连线的颜色
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
g.nodes().length-1
|
}
|
||||||
g.nodes().forEach(function (v) {
|
that.sort = dat[0].sort;
|
||||||
console.log("Node " + v + ": " + JSON.stringify(g.node(v)));
|
that.actives = that.flowSteps.indexOf(dat[0]);
|
||||||
});
|
if( that.flowSteps.length-that.actives >1){}else{
|
||||||
// 创建渲染器
|
that.actives =that.flowSteps.length;
|
||||||
let render = new dagreD3.render();
|
}
|
||||||
// 选择 svg 并添加一个g元素作为绘图容器.
|
var g = new dagreD3.graphlib.Graph().setGraph({
|
||||||
let svg = d3.select('#mySvg');
|
rankdir: 'DL',
|
||||||
let svgGroup = svg.append('g');
|
nodesep: 100,
|
||||||
let zoom = d3.zoom()
|
edgesep: 10,//两条线之间的距离
|
||||||
.on("zoom", function() {
|
ranksep: 50,//节点之间的距离
|
||||||
svgGroup.attr("transform", d3.event.transform);
|
marginx: 60,
|
||||||
});
|
marginy: 20,
|
||||||
svg.call(zoom);
|
});
|
||||||
// 在绘图容器上运行渲染器生成流程图.
|
//获取state得到节点
|
||||||
render(d3.select("svg g"), g);
|
getWfStateList(workflow).then((response) => {
|
||||||
// this.getTicketFlowlogs(ticketId);
|
if (response.data) {
|
||||||
getTicketFlowlog(ticketId).then(res=>{
|
let nodes = response.data;
|
||||||
if(res.data){
|
|
||||||
that.logs = res.data;
|
|
||||||
svgGroup
|
|
||||||
.selectAll('g.node')
|
|
||||||
.on('mouseover', (v) => {
|
|
||||||
// 假如当前toolText为"",则不展示
|
|
||||||
//这里就是自定义tooltip的内容
|
|
||||||
let filList = [], strList = [];
|
|
||||||
filList = nodes.filter((ii) => {
|
|
||||||
return ii.name === g.node(v).label
|
|
||||||
})
|
|
||||||
if (!filList.length) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
filList.map((k) => {
|
|
||||||
let filte = that.logs.filter(item=>{
|
|
||||||
return item.state == k.id;
|
|
||||||
})
|
|
||||||
//每个
|
|
||||||
let str = '处理人:'+filte[0].participant_.name;
|
|
||||||
strList.push(str)
|
|
||||||
})
|
|
||||||
that.tipVisible(strList)
|
|
||||||
})
|
|
||||||
.on('mouseout', () => {
|
|
||||||
this.tipHidden()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}else{}
|
// 添加节点
|
||||||
});
|
nodes.forEach((item) => {
|
||||||
}
|
if(item.sort==that.sort){
|
||||||
});
|
g.setNode(item.id, {
|
||||||
}
|
// 节点标签
|
||||||
});
|
label: item.name,
|
||||||
}
|
// 节点形状
|
||||||
|
shape: 'rect',
|
||||||
|
toolText: item.name,
|
||||||
|
//节点样式
|
||||||
|
style: "fill:#409EFF;stroke:#000",
|
||||||
|
labelStyle: "fill:#000;",
|
||||||
|
rx :5,//矩形节点圆角度
|
||||||
|
ry :5
|
||||||
|
});
|
||||||
|
|
||||||
|
}else{
|
||||||
|
g.setNode(item.id, {
|
||||||
|
// 节点标签
|
||||||
|
label: item.name,
|
||||||
|
// 节点形状
|
||||||
|
shape: 'rect',
|
||||||
|
toolText: item.name,
|
||||||
|
//节点样式
|
||||||
|
style: "fill:#fff;stroke:#000",
|
||||||
|
labelStyle: "fill:#000;",
|
||||||
|
rx :5,//矩形节点圆角度
|
||||||
|
ry :5
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
g.nodes().forEach(function (v) {
|
||||||
|
console.log("Node " + v + ": " + JSON.stringify(g.node(v)));
|
||||||
|
});
|
||||||
|
//获取流转得到线 链接关系
|
||||||
|
getWfTransitionList(workflow).then((res)=>{
|
||||||
|
if(res.data){
|
||||||
|
let transitionList = res.data;
|
||||||
|
transitionList.forEach((transitions)=>{
|
||||||
|
let transition0 = transitions;
|
||||||
|
if (transition0.condition_expression.length>0){
|
||||||
|
g.setNode(transition0.source_state_.id+100000, {label: "条件表达式", style: "fill: #a4d088", shape: "diamond"});
|
||||||
|
g.setEdge(transition0.source_state_.id, transition0.source_state_.id+100000, {
|
||||||
|
// 边标签
|
||||||
|
label: transition0.name,
|
||||||
|
style: "fill:#ffffff;stroke:#c0c1c3;stroke-width:1.5px"
|
||||||
|
});
|
||||||
|
let condition_expression = transition0.condition_expression;
|
||||||
|
condition_expression.forEach(condition_expression0=>{
|
||||||
|
g.setEdge(transition0.source_state_.id+100000, condition_expression0.target_state, {
|
||||||
|
label: condition_expression0.label,
|
||||||
|
style: "fill:#ffffff;stroke:#c0c1c3;stroke-width:1.5px"
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
g.setEdge(transition0.source_state_.id, transition0.destination_state_.id, {
|
||||||
|
// 边标签
|
||||||
|
label: transition0.name,
|
||||||
|
// 边样式
|
||||||
|
style: "fill:#ffffff;stroke:#c0c1c3;stroke-width:1.5px" // 根据后台数据来改变连线的颜色
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
g.nodes().length-1
|
||||||
|
g.nodes().forEach(function (v) {
|
||||||
|
console.log("Node " + v + ": " + JSON.stringify(g.node(v)));
|
||||||
|
});
|
||||||
|
// 创建渲染器
|
||||||
|
let render = new dagreD3.render();
|
||||||
|
// 选择 svg 并添加一个g元素作为绘图容器.
|
||||||
|
let svg = d3.select('#mySvg');
|
||||||
|
let svgGroup = svg.append('g');
|
||||||
|
let zoom = d3.zoom()
|
||||||
|
.on("zoom", function() {
|
||||||
|
svgGroup.attr("transform", d3.event.transform);
|
||||||
|
});
|
||||||
|
svg.call(zoom);
|
||||||
|
// 在绘图容器上运行渲染器生成流程图.
|
||||||
|
render(d3.select("svg g"), g);
|
||||||
|
// this.getTicketFlowlogs(ticketId);
|
||||||
|
getTicketFlowlog(ticketId).then(res=>{
|
||||||
|
if(res.data){
|
||||||
|
that.logs = res.data;
|
||||||
|
svgGroup
|
||||||
|
.selectAll('g.node')
|
||||||
|
.on('mouseover', (v) => {
|
||||||
|
// 假如当前toolText为"",则不展示
|
||||||
|
//这里就是自定义tooltip的内容
|
||||||
|
let filList = [], strList = [];
|
||||||
|
filList = nodes.filter((ii) => {
|
||||||
|
return ii.name === g.node(v).label
|
||||||
|
})
|
||||||
|
if (!filList.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
filList.map((k) => {
|
||||||
|
let filte = that.logs.filter(item=>{
|
||||||
|
return item.state == k.id;
|
||||||
|
})
|
||||||
|
//每个
|
||||||
|
let str = '处理人:'+filte[0].participant_.name;
|
||||||
|
strList.push(str)
|
||||||
|
})
|
||||||
|
that.tipVisible(strList)
|
||||||
|
})
|
||||||
|
.on('mouseout', () => {
|
||||||
|
this.tipHidden()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}else{}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
activated(){
|
activated(){
|
||||||
|
|
@ -498,7 +532,6 @@
|
||||||
.style('left', `${d3.event.pageX + 15}px`)
|
.style('left', `${d3.event.pageX + 15}px`)
|
||||||
.style('top', `${d3.event.pageY-10}px`)
|
.style('top', `${d3.event.pageY-10}px`)
|
||||||
},
|
},
|
||||||
|
|
||||||
// tooltip隐藏
|
// tooltip隐藏
|
||||||
tipHidden() {
|
tipHidden() {
|
||||||
this.tooltip
|
this.tooltip
|
||||||
|
|
@ -588,9 +621,6 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
addNode(){
|
|
||||||
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -247,6 +247,7 @@
|
||||||
>报废
|
>报废
|
||||||
</el-link>!-->
|
</el-link>!-->
|
||||||
<el-link type="primary"
|
<el-link type="primary"
|
||||||
|
v-if="!scope.row.ticket"
|
||||||
@click="handleRetrial(scope)"
|
@click="handleRetrial(scope)"
|
||||||
>重审
|
>重审
|
||||||
</el-link>
|
</el-link>
|
||||||
|
|
@ -508,98 +509,78 @@
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!--不合格半成品重审-->
|
<!--不合格半成品重审-->
|
||||||
<el-dialog title="不合格半成品重审" :close-on-click-modal="false" :visible.sync="limitedRetrial">
|
<el-dialog title="不合格半成品重审" :close-on-click-modal="false" :visible.sync="limitedRetrial">
|
||||||
<el-form label-width="80px" label-position="right">
|
<el-form label-width="130px" label-position="right">
|
||||||
<el-row v-for="(item, $index) in fieldList.record_data" :key="$index">
|
<el-form-item :label="item.field_name" v-for="item in customfieldList" :key="item.id" v-show="!item.is_hidden">
|
||||||
<el-form-item
|
<template v-if="item.field_type=='string'">
|
||||||
v-if="item.field_type === 'string'"
|
<el-input v-model="item.default_value" :placeholder="item.description" />
|
||||||
:label="item.field_name"
|
</template>
|
||||||
>
|
<template v-if="item.field_type==='int'">
|
||||||
<el-input placeholder="请输入" v-model="item.sort" />
|
<el-input v-model="item.default_value" type="number" :placeholder="item.description" oninput="value=value.replace(/[^\d]/g,'')" />
|
||||||
</el-form-item>
|
</template>
|
||||||
<el-form-item
|
<template v-if="item.field_type==='float'">
|
||||||
v-else-if="item.field_type === 'int'"
|
<el-input v-model="item.default_value" type="number" :placeholder="item.description" />
|
||||||
:label="item.field_name"
|
</template>
|
||||||
>
|
<template v-if="item.field_type==='date'">
|
||||||
<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
|
<el-date-picker
|
||||||
v-model="item.create_time"
|
v-model="item.default_value"
|
||||||
type="date"
|
type="date"
|
||||||
placeholder="选择日期"
|
placeholder="选择日期"
|
||||||
value-format="yyyy-MM-dd"
|
value-format="yyyy-MM-dd"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
>
|
>
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
</el-form-item>
|
</template>
|
||||||
<el-form-item
|
<template v-if="item.field_type==='datetime'">
|
||||||
v-else-if="item.field_type === 'datetime'"
|
|
||||||
:label="item.field_name"
|
|
||||||
>
|
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="item.create_time"
|
v-model="item.default_value"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
placeholder="选择日期"
|
placeholder="选择日期"
|
||||||
value-format="yyyy-MM-dd HH:mm:ss"
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
>
|
>
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
</el-form-item>
|
</template>
|
||||||
<el-form-item
|
<template v-if="item.field_type==='select'">
|
||||||
v-else-if="item.field_type === 'select'"
|
<el-select style="width: 100%" v-model="item.default_value" placeholder="请选择">
|
||||||
:label="item.field_name"
|
|
||||||
>
|
|
||||||
<el-select
|
|
||||||
style="width: 100%"
|
|
||||||
v-model="item.sort"
|
|
||||||
placeholder="请选择"
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item1 in item.field_choice"
|
v-for="item1 in item.field_choice"
|
||||||
:key="item1"
|
:key="item1.id"
|
||||||
:label="item1"
|
:label="item1.name"
|
||||||
:value="item1"
|
:value="item1.id"
|
||||||
>
|
>
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</template>
|
||||||
<el-form-item
|
<template v-if="item.field_type==='selects'">
|
||||||
v-else-if="item.field_type === 'selects'"
|
<el-select style="width: 100%" multiple v-model="item.default_value" placeholder="请选择">
|
||||||
:label="item.field_name"
|
|
||||||
>
|
|
||||||
<el-select
|
|
||||||
style="width: 100%"
|
|
||||||
v-model="optio"
|
|
||||||
multiple
|
|
||||||
placeholder="请选择"
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item1 in item.field_choice"
|
v-for="item1 in item.field_choice"
|
||||||
:key="item1"
|
:key="item1.id"
|
||||||
:label="item1"
|
:label="item1.name"
|
||||||
:value="item1"
|
:value="item1.id"
|
||||||
>
|
>
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</template>
|
||||||
</el-row>
|
<template v-if="item.field_type==='textarea'">
|
||||||
|
<el-input type="textarea" :rows="3" v-model="item.default_value" placeholder="内容" />
|
||||||
|
</template>
|
||||||
|
<template v-if="item.field_type==='file'">
|
||||||
|
<el-upload
|
||||||
|
ref="upload"
|
||||||
|
:action="upUrl"
|
||||||
|
:on-preview="handlePreview"
|
||||||
|
:on-success="handleUpSuccess"
|
||||||
|
:on-remove="handleRemove"
|
||||||
|
:headers="upHeaders"
|
||||||
|
:file-list="fileList"
|
||||||
|
:limit="1"
|
||||||
|
accept=".doc,.docx,.xls,.xlsx,.ppt,.pptx"
|
||||||
|
>
|
||||||
|
<el-button size="small" type="primary">上传文件</el-button>
|
||||||
|
</el-upload>
|
||||||
|
</template>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button @click="limitedRetrial = false">取 消</el-button>
|
<el-button @click="limitedRetrial = false">取 消</el-button>
|
||||||
|
|
@ -609,12 +590,15 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import { getOrgAll } from "@/api/org";
|
||||||
|
import { getUserList } from "@/api/user";
|
||||||
|
import {getWarehouseList} from "@/api/inm";
|
||||||
|
import checkPermission from "@/utils/permission";
|
||||||
import customForm from '@/components/customForm/index';
|
import customForm from '@/components/customForm/index';
|
||||||
import reviewForm from '@/components/customForm/review';
|
import reviewForm from '@/components/customForm/review';
|
||||||
import {getwproductList, wproductTest, wproductPutin, createputins,testInit,scrap,getRetrial} from "@/api/wpm";
|
import {getWfCustomfieldList,createTicket ,getWorkflowInit} from "@/api/workflow";
|
||||||
import checkPermission from "@/utils/permission";
|
|
||||||
import {getWarehouseList} from "@/api/inm";
|
|
||||||
import {getMaterialList, getrecordformList, getrffieldList} from "@/api/mtm";
|
import {getMaterialList, getrecordformList, getrffieldList} from "@/api/mtm";
|
||||||
|
import {getwproductList, wproductTest, wproductPutin, createputins,testInit,scrap,getRetrial} from "@/api/wpm";
|
||||||
import {getTestRecord,getTestRecordItem,putTestRecordItem,delTestRecordItem,subTestRecordItem} from "@/api/qm";
|
import {getTestRecord,getTestRecordItem,putTestRecordItem,delTestRecordItem,subTestRecordItem} from "@/api/qm";
|
||||||
import {genTree} from "@/utils";
|
import {genTree} from "@/utils";
|
||||||
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
||||||
|
|
@ -698,13 +682,17 @@
|
||||||
{ lable: "其他", value: 40 },
|
{ lable: "其他", value: 40 },
|
||||||
],
|
],
|
||||||
recordList: [],
|
recordList: [],
|
||||||
|
transitions: null,
|
||||||
options: [],
|
options: [],
|
||||||
listLoading: true,
|
listLoading: true,
|
||||||
fieldList: [],
|
fieldList: [],
|
||||||
originList: [],
|
originList: [],
|
||||||
is_testok: "true",
|
is_testok: "true",
|
||||||
field: [],
|
field: [],
|
||||||
|
userList: [],//用户列表
|
||||||
|
orgList: [],//部门列表
|
||||||
recordformList: [],
|
recordformList: [],
|
||||||
|
customfieldList: [],
|
||||||
recordform: null,
|
recordform: null,
|
||||||
recordId: null,
|
recordId: null,
|
||||||
fifo_detail: "",
|
fifo_detail: "",
|
||||||
|
|
@ -728,6 +716,15 @@
|
||||||
dialogFormVisibles: false,
|
dialogFormVisibles: false,
|
||||||
limitedCheckRecord: false,
|
limitedCheckRecord: false,
|
||||||
testrecord: {},
|
testrecord: {},
|
||||||
|
retrialItem: {},//复检对象
|
||||||
|
retrialResponse: {},//复检对象
|
||||||
|
//复检表单
|
||||||
|
retrialForm: {
|
||||||
|
title:'',
|
||||||
|
transition:null,
|
||||||
|
workflow:'',
|
||||||
|
ticket_data:{},
|
||||||
|
},
|
||||||
WarehouseData: "",
|
WarehouseData: "",
|
||||||
formName: '项目检查表',
|
formName: '项目检查表',
|
||||||
};
|
};
|
||||||
|
|
@ -823,14 +820,64 @@
|
||||||
},
|
},
|
||||||
//不合格产品重审展示
|
//不合格产品重审展示
|
||||||
handleRetrial(scope){
|
handleRetrial(scope){
|
||||||
|
let that =this;
|
||||||
|
this.retrialItem = Object.assign({}, scope.row);
|
||||||
|
console.log(this.retrialItem);
|
||||||
getRetrial(scope.row.id).then(res=>{
|
getRetrial(scope.row.id).then(res=>{
|
||||||
debugger;
|
that.retrialResponse = res.data;
|
||||||
console.log(res)
|
getWorkflowInit(res.data.workflow).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
debugger;
|
||||||
|
console.log(response.data);
|
||||||
|
that.retrialForm.transition = response.data.transitions[0].id;
|
||||||
|
that.customfieldList = response.data.field_list;
|
||||||
|
for (let i=0;i<that.customfieldList.length;i++) {
|
||||||
|
if(that.customfieldList[i].field_key==="wproduct"){
|
||||||
|
that.customfieldList[i].default_value = that.retrialResponse.exist_data.wproduct;
|
||||||
|
}
|
||||||
|
if(that.customfieldList[i].field_key==="wproduct_name"){
|
||||||
|
that.customfieldList[i].default_value = that.retrialResponse.exist_data.wproduct_name;
|
||||||
|
}
|
||||||
|
if(that.customfieldList[i].field_key==="wproduct_type"){
|
||||||
|
that.customfieldList[i].default_value = that.retrialResponse.exist_data.wproduct_specification;
|
||||||
|
}
|
||||||
|
if(that.customfieldList[i].field_key==="finder"){
|
||||||
|
that.customfieldList[i].default_value = that.retrialResponse.exist_data.finder;
|
||||||
|
}
|
||||||
|
if(that.customfieldList[i].field_key==="find_process"){
|
||||||
|
that.customfieldList[i].default_value = that.retrialResponse.exist_data.find_process;
|
||||||
|
}
|
||||||
|
if(that.customfieldList[i].label==="sys_user"){
|
||||||
|
that.customfieldList[i].field_choice = that.userList;
|
||||||
|
}
|
||||||
|
if(that.customfieldList[i].label==="deptSelect"){
|
||||||
|
that.customfieldList[i].field_choice = that.orgList;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
that.limitedRetrial = true;
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
//不合格产品重审提交
|
//不合格产品重审提交
|
||||||
retrialSubmit(){
|
retrialSubmit(){
|
||||||
|
let that = this;
|
||||||
|
let fields = this.customfieldList;
|
||||||
|
let obj = new Object();
|
||||||
|
for(let i=0;i<fields.length;i++){
|
||||||
|
obj[fields[i].field_key] = fields[i].default_value
|
||||||
|
}
|
||||||
|
this.retrialForm.ticket_data = obj;
|
||||||
|
this.retrialForm.workflow = that.retrialResponse.workflow;
|
||||||
|
this.retrialForm.title = that.retrialResponse.exist_data.wproduct_name+'的重审';
|
||||||
|
createTicket(this.retrialForm).then((res) => {
|
||||||
|
if (res.code >= 200) {
|
||||||
|
this.getList4();
|
||||||
|
this.limitedRetrial = false;
|
||||||
|
this.$message.success("成功");
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
//夹层半成品列表
|
//夹层半成品列表
|
||||||
getList3() {
|
getList3() {
|
||||||
|
|
@ -880,7 +927,6 @@
|
||||||
//点击检验:如果有一个直接进入,如果有多个表再进行选择
|
//点击检验:如果有一个直接进入,如果有多个表再进行选择
|
||||||
handleInspection(scope,index) {
|
handleInspection(scope,index) {
|
||||||
//调该物料对应的检查表
|
//调该物料对应的检查表
|
||||||
// debugger;
|
|
||||||
let that = this;
|
let that = this;
|
||||||
this.innerIndex = index;
|
this.innerIndex = index;
|
||||||
// this.outerVisible = true;
|
// this.outerVisible = true;
|
||||||
|
|
@ -890,7 +936,6 @@
|
||||||
this.recordform = null;
|
this.recordform = null;
|
||||||
getrecordformList(this.listQueryrecordform).then((response) => {
|
getrecordformList(this.listQueryrecordform).then((response) => {
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
debugger;
|
|
||||||
this.recordformList = response.data;
|
this.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;
|
||||||
|
|
@ -921,7 +966,6 @@
|
||||||
that.limitedCheckRecord = true;
|
that.limitedCheckRecord = true;
|
||||||
getTestRecord({wproduct:scope.row.id}).then(res=>{
|
getTestRecord({wproduct:scope.row.id}).then(res=>{
|
||||||
if(res.code==200){
|
if(res.code==200){
|
||||||
debugger;
|
|
||||||
that.recordList = res.data.results;
|
that.recordList = res.data.results;
|
||||||
}else{
|
}else{
|
||||||
this.$message.error(res.msg);
|
this.$message.error(res.msg);
|
||||||
|
|
@ -930,7 +974,6 @@
|
||||||
},
|
},
|
||||||
//点击记录里的检验
|
//点击记录里的检验
|
||||||
handleInspectionRecord(scope){
|
handleInspectionRecord(scope){
|
||||||
// debugger;
|
|
||||||
let that =this;
|
let that =this;
|
||||||
that.recordVisible = false;
|
that.recordVisible = false;
|
||||||
that.recordId = scope.row.id;
|
that.recordId = scope.row.id;
|
||||||
|
|
@ -949,7 +992,6 @@
|
||||||
that.hasPicture = true;
|
that.hasPicture = true;
|
||||||
}
|
}
|
||||||
getTestRecordItem(scope.row.id).then((res) => {
|
getTestRecordItem(scope.row.id).then((res) => {
|
||||||
// debugger;
|
|
||||||
let arr = [];
|
let arr = [];
|
||||||
let fieldList = res.data.record_data;
|
let fieldList = res.data.record_data;
|
||||||
for(let i=0;i<that.fieldList.length;i++){
|
for(let i=0;i<that.fieldList.length;i++){
|
||||||
|
|
@ -972,7 +1014,6 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}else if(that.innerIndex==='2'){//复检
|
}else if(that.innerIndex==='2'){//复检
|
||||||
debugger;
|
|
||||||
getTestRecordItem(scope.row.id).then((res) => {
|
getTestRecordItem(scope.row.id).then((res) => {
|
||||||
if (res.data) {
|
if (res.data) {
|
||||||
that.hasPicture = false;
|
that.hasPicture = false;
|
||||||
|
|
@ -995,8 +1036,6 @@
|
||||||
}
|
}
|
||||||
that.fieldList.push(obj)
|
that.fieldList.push(obj)
|
||||||
}
|
}
|
||||||
debugger;
|
|
||||||
console.log(that.fieldList)
|
|
||||||
// that.fieldList = [...fieldList];
|
// that.fieldList = [...fieldList];
|
||||||
let arr = fieldList.filter(item => {
|
let arr = fieldList.filter(item => {
|
||||||
return item.field_type === 'draw'
|
return item.field_type === 'draw'
|
||||||
|
|
@ -1015,11 +1054,9 @@
|
||||||
},
|
},
|
||||||
//半产品复检
|
//半产品复检
|
||||||
handleReview() {
|
handleReview() {
|
||||||
// debugger;
|
|
||||||
let that = this;
|
let that = this;
|
||||||
testInit({ wproduct: this.wproduct,form: that.recordform}).then((response) => {
|
testInit({ wproduct: this.wproduct,form: that.recordform}).then((response) => {
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
debugger;
|
|
||||||
that.hasPicture = false;
|
that.hasPicture = false;
|
||||||
that.recordId = response.data.id;
|
that.recordId = response.data.id;
|
||||||
that.formName = response.data.form_.name;
|
that.formName = response.data.form_.name;
|
||||||
|
|
@ -1054,7 +1091,6 @@
|
||||||
|
|
||||||
//根据选择的表,渲染检查项目
|
//根据选择的表,渲染检查项目
|
||||||
submitrecordform(index) {
|
submitrecordform(index) {
|
||||||
// debugger;
|
|
||||||
let that = this;
|
let that = this;
|
||||||
this.outerVisible = false;
|
this.outerVisible = false;
|
||||||
if (that.recordform != "") {
|
if (that.recordform != "") {
|
||||||
|
|
@ -1080,7 +1116,6 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}else if(index==='2'){//复检
|
}else if(index==='2'){//复检
|
||||||
// debugger;
|
|
||||||
that.handleReview();
|
that.handleReview();
|
||||||
}
|
}
|
||||||
} else this.$message.error("请选择检查表!");
|
} else this.$message.error("请选择检查表!");
|
||||||
|
|
@ -1145,7 +1180,6 @@
|
||||||
params.record_data = value.record_data;
|
params.record_data = value.record_data;
|
||||||
params.is_testok = value.is_testok;
|
params.is_testok = value.is_testok;
|
||||||
putTestRecordItem(id,params).then((res) => {
|
putTestRecordItem(id,params).then((res) => {
|
||||||
// debugger;
|
|
||||||
if (res.code >= 200) {
|
if (res.code >= 200) {
|
||||||
that.recordVisible = false;
|
that.recordVisible = false;
|
||||||
that.limitedReview = false;
|
that.limitedReview = false;
|
||||||
|
|
@ -1202,5 +1236,15 @@
|
||||||
this.reload()
|
this.reload()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
getUserList({page:0}).then(response => {
|
||||||
|
if (response.data) {
|
||||||
|
this.userList = response.data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
getOrgAll().then((response) => {
|
||||||
|
this.orgList = response.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@
|
||||||
v-if="item.field_type === 'string'"
|
v-if="item.field_type === 'string'"
|
||||||
:label="item.field_name"
|
:label="item.field_name"
|
||||||
>
|
>
|
||||||
<el-input placeholder="请输入" v-model="item.sort" />
|
<el-input v-model="item.field_value" placeholder="请输入"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-else-if="item.field_type === 'int'"
|
v-else-if="item.field_type === 'int'"
|
||||||
|
|
@ -196,7 +196,7 @@
|
||||||
<el-input
|
<el-input
|
||||||
type="number"
|
type="number"
|
||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
v-model="item.sort"
|
v-model="item.field_value"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
|
|
@ -206,7 +206,7 @@
|
||||||
<el-input
|
<el-input
|
||||||
type="number"
|
type="number"
|
||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
v-model="item.sort"
|
v-model="item.field_value"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
|
|
@ -214,7 +214,7 @@
|
||||||
:label="item.field_name"
|
:label="item.field_name"
|
||||||
>
|
>
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="item.create_time"
|
v-model="item.field_value"
|
||||||
type="date"
|
type="date"
|
||||||
placeholder="选择日期"
|
placeholder="选择日期"
|
||||||
value-format="yyyy-MM-dd"
|
value-format="yyyy-MM-dd"
|
||||||
|
|
@ -227,7 +227,7 @@
|
||||||
:label="item.field_name"
|
:label="item.field_name"
|
||||||
>
|
>
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="item.create_time"
|
v-model="item.field_value"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
placeholder="选择日期"
|
placeholder="选择日期"
|
||||||
value-format="yyyy-MM-dd HH:mm:ss"
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
|
@ -241,7 +241,7 @@
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
v-model="item.sort"
|
v-model="item.field_value"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
|
|
@ -259,7 +259,7 @@
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
v-model="optio"
|
v-model="item.field_value"
|
||||||
multiple
|
multiple
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
>
|
>
|
||||||
|
|
@ -604,6 +604,7 @@ export default {
|
||||||
},
|
},
|
||||||
fieldList: {
|
fieldList: {
|
||||||
count: 0,
|
count: 0,
|
||||||
|
name:'',
|
||||||
},
|
},
|
||||||
listQueryfield: {
|
listQueryfield: {
|
||||||
page: 1,
|
page: 1,
|
||||||
|
|
@ -798,7 +799,9 @@ export default {
|
||||||
this.formID = scope.row.id;
|
this.formID = scope.row.id;
|
||||||
recordInit( this.formID).then((response) => {
|
recordInit( this.formID).then((response) => {
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
|
debugger;
|
||||||
this.fieldList = response.data;
|
this.fieldList = response.data;
|
||||||
|
this.fieldList.name = response.data.form_.name;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.dialogVisibleForm = true;
|
this.dialogVisibleForm = true;
|
||||||
|
|
@ -820,16 +823,21 @@ export default {
|
||||||
let _this = this;
|
let _this = this;
|
||||||
_this.record_data = []; //检查项目
|
_this.record_data = []; //检查项目
|
||||||
this.fieldList.record_data.forEach((item) => {
|
this.fieldList.record_data.forEach((item) => {
|
||||||
|
if(item.field_type==='int'){
|
||||||
|
item.field_value = parseInt(item.field_value)
|
||||||
|
}else if(item.field_type==='float'){
|
||||||
|
item.field_value = parseFloat(item.field_value)
|
||||||
|
}
|
||||||
_this.record_data.push({
|
_this.record_data.push({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
field_value: item.field_value,
|
field_value:item.field_value,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.record.record_data = _this.record_data;
|
this.record.record_data = _this.record_data;
|
||||||
createRecord(this.formID, this.record).then((res) => {
|
createRecord(this.formID, this.record).then((res) => {
|
||||||
if (res.code >= 200) {
|
if (res.code >= 200) {
|
||||||
this.getrecordLists();
|
this.getrecordLists();
|
||||||
this.$message.success("创建成功!");
|
this.$message.success("提交成功!");
|
||||||
|
|
||||||
this.dialogVisibleForm = false;
|
this.dialogVisibleForm = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class DevelopConfig(AppConfig):
|
||||||
|
name = 'apps.develop'
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
# Create your models here.
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
from django.db.models import base
|
||||||
|
from rest_framework import urlpatterns
|
||||||
|
from django.urls import path, include
|
||||||
|
from rest_framework.routers import DefaultRouter
|
||||||
|
from apps.develop.views import CleanDataView
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('cleandata/', CleanDataView.as_view()),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
from django.shortcuts import render
|
||||||
|
from rest_framework.views import APIView
|
||||||
|
from rest_framework.permissions import IsAdminUser
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from apps.inm.models import FIFO, Inventory, MaterialBatch
|
||||||
|
from apps.mtm.models import Material
|
||||||
|
from apps.pm.models import ProductionPlan
|
||||||
|
from apps.sam.models import Order
|
||||||
|
from apps.wf.models import Ticket
|
||||||
|
from apps.wpm.models import Operation
|
||||||
|
# Create your views here.
|
||||||
|
|
||||||
|
class CleanDataView(APIView):
|
||||||
|
permission_classes = [IsAdminUser]
|
||||||
|
|
||||||
|
def post(self, request, format=None):
|
||||||
|
"""
|
||||||
|
清空数据库
|
||||||
|
"""
|
||||||
|
Order.objects.all().delete(soft=False)
|
||||||
|
ProductionPlan.objects.all().delete(soft=False)
|
||||||
|
FIFO.objects.all().delete(soft=False)
|
||||||
|
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()
|
||||||
|
return Response()
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-27 01:48
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('wpm', '0038_auto_20211227_0948'),
|
||||||
|
('inm', '0023_auto_20211216_0945'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='fifoitemproduct',
|
||||||
|
name='wproduct',
|
||||||
|
field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='fifoitem_wproduct', to='wpm.wproduct', verbose_name='关联的动态产品'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='iproduct',
|
||||||
|
name='wproduct',
|
||||||
|
field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='iproduct_wproduct', to='wpm.wproduct', verbose_name='关联的动态产品'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -92,7 +92,8 @@ class IProduct(BaseModel):
|
||||||
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
||||||
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
||||||
batch = models.CharField('所属批次号', max_length=100, default='')
|
batch = models.CharField('所属批次号', max_length=100, default='')
|
||||||
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True)
|
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False,
|
||||||
|
null=True, blank=True, related_name='iproduct_wproduct')
|
||||||
is_mtested = models.BooleanField('是否军检', default=False)
|
is_mtested = models.BooleanField('是否军检', default=False)
|
||||||
is_mtestok = models.BooleanField('是否军检合格', null=True, blank=True)
|
is_mtestok = models.BooleanField('是否军检合格', null=True, blank=True)
|
||||||
remark_mtest = models.TextField('军检备注', null=True, blank=True)
|
remark_mtest = models.TextField('军检备注', null=True, blank=True)
|
||||||
|
|
@ -103,7 +104,8 @@ class FIFOItemProduct(BaseModel):
|
||||||
出入库产品
|
出入库产品
|
||||||
"""
|
"""
|
||||||
fifoitem = models.ForeignKey(FIFOItem, verbose_name='关联出入库具体产品', on_delete=models.CASCADE)
|
fifoitem = models.ForeignKey(FIFOItem, verbose_name='关联出入库具体产品', on_delete=models.CASCADE)
|
||||||
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True)
|
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True,
|
||||||
|
related_name='fifoitem_wproduct')
|
||||||
number = models.CharField('物品编号', max_length=50)
|
number = models.CharField('物品编号', max_length=50)
|
||||||
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
||||||
iproduct = models.ForeignKey(IProduct, verbose_name='关联库存产品', null=True, blank=True, on_delete=models.SET_NULL)
|
iproduct = models.ForeignKey(IProduct, verbose_name='关联库存产品', null=True, blank=True, on_delete=models.SET_NULL)
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
perms_map = {'*': '*'}
|
perms_map = {'*': '*'}
|
||||||
queryset = FIFOItem.objects.select_related('material', 'fifo').all()
|
queryset = FIFOItem.objects.select_related('material', 'fifo').all()
|
||||||
serializer_class = FIFOItemSerializer
|
serializer_class = FIFOItemSerializer
|
||||||
filterset_fields = ['material', 'fifo']
|
filterset_fields = ['material', 'fifo', 'fifo__type', 'is_tested', 'is_testok']
|
||||||
search_fields = []
|
search_fields = []
|
||||||
ordering_fields = ['create_time']
|
ordering_fields = ['create_time']
|
||||||
ordering = ['-create_time']
|
ordering = ['-create_time']
|
||||||
|
|
@ -99,13 +99,7 @@ class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
obj = serializer.save(create_by = self.request.user)
|
obj = serializer.save(create_by = self.request.user)
|
||||||
tris = []
|
tris = []
|
||||||
for m in record_data: # 保存记录详情
|
for m in record_data: # 保存记录详情
|
||||||
form_field = m['form_field']
|
|
||||||
m['field_name'] = form_field.field_name
|
|
||||||
m['field_key'] = form_field.field_key
|
|
||||||
m['field_type'] = form_field.field_type
|
|
||||||
m['field_value'] = m['field_value']
|
m['field_value'] = m['field_value']
|
||||||
m['sort'] = form_field.sort
|
|
||||||
m['need_judge'] = form_field.need_judge
|
|
||||||
m['is_testok'] = m['is_testok'] if 'is_testok' in m else True
|
m['is_testok'] = m['is_testok'] if 'is_testok' in m else True
|
||||||
m['test_record'] = obj
|
m['test_record'] = obj
|
||||||
tris.append(TestRecordItem(**m))
|
tris.append(TestRecordItem(**m))
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-27 05:18
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('pm', '0017_auto_20211213_1401'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='productionplan',
|
||||||
|
name='process_json',
|
||||||
|
field=models.JSONField(blank=True, default=list, null=True, verbose_name='按工序的统计数'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-28 06:17
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('pm', '0018_productionplan_process_json'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='productionplan',
|
||||||
|
name='process_json',
|
||||||
|
field=models.JSONField(blank=True, default=dict, null=True, verbose_name='按工序的统计数'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-29 01:12
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('pm', '0019_alter_productionplan_process_json'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='productionplan',
|
||||||
|
name='count_notok',
|
||||||
|
field=models.PositiveIntegerField(default=0, verbose_name='不合格数量'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='subproductionplan',
|
||||||
|
name='main_count_notok',
|
||||||
|
field=models.PositiveIntegerField(default=0, verbose_name='不合格数量'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='subproductionprogress',
|
||||||
|
name='count_notok',
|
||||||
|
field=models.PositiveIntegerField(default=0, verbose_name='不合格数量'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='subproductionprogress',
|
||||||
|
name='count',
|
||||||
|
field=models.PositiveIntegerField(verbose_name='应出入数'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='subproductionprogress',
|
||||||
|
name='count_ok',
|
||||||
|
field=models.PositiveIntegerField(default=0, verbose_name='合格数量'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='subproductionprogress',
|
||||||
|
name='count_pick',
|
||||||
|
field=models.PositiveIntegerField(default=0, verbose_name='实际领用数'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='subproductionprogress',
|
||||||
|
name='count_real',
|
||||||
|
field=models.PositiveIntegerField(default=0, verbose_name='实际消耗/产出数'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -27,8 +27,10 @@ class ProductionPlan(CommonAModel):
|
||||||
count = models.PositiveIntegerField('生产数量', default=1)
|
count = models.PositiveIntegerField('生产数量', default=1)
|
||||||
count_real = models.PositiveIntegerField('实际产出数', default=0)
|
count_real = models.PositiveIntegerField('实际产出数', default=0)
|
||||||
count_ok = models.PositiveIntegerField('合格数', default=0)
|
count_ok = models.PositiveIntegerField('合格数', default=0)
|
||||||
|
count_notok = models.PositiveIntegerField('不合格数量', default=0)
|
||||||
start_date = models.DateField('计划开工日期')
|
start_date = models.DateField('计划开工日期')
|
||||||
end_date = models.DateField('计划完工日期')
|
end_date = models.DateField('计划完工日期')
|
||||||
|
process_json = models.JSONField('按工序的统计数', default=dict, null=True, blank=True)
|
||||||
is_planed = models.BooleanField('是否已排产', default=False)
|
is_planed = models.BooleanField('是否已排产', default=False)
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = '生产计划'
|
verbose_name = '生产计划'
|
||||||
|
|
@ -66,6 +68,7 @@ class SubProductionPlan(CommonAModel):
|
||||||
main_count = models.PositiveIntegerField('应产出数', default=0)
|
main_count = models.PositiveIntegerField('应产出数', default=0)
|
||||||
main_count_real = models.PositiveIntegerField('实际产出数', default=0)
|
main_count_real = models.PositiveIntegerField('实际产出数', default=0)
|
||||||
main_count_ok = models.PositiveIntegerField('合格数', default=0)
|
main_count_ok = models.PositiveIntegerField('合格数', default=0)
|
||||||
|
main_count_notok = models.PositiveIntegerField('不合格数量', default=0)
|
||||||
|
|
||||||
steps = models.JSONField('工艺步骤', default=list)
|
steps = models.JSONField('工艺步骤', default=list)
|
||||||
|
|
||||||
|
|
@ -87,7 +90,8 @@ class SubProductionProgress(BaseModel):
|
||||||
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE)
|
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE)
|
||||||
is_main = models.BooleanField('是否主产出', default=False)
|
is_main = models.BooleanField('是否主产出', default=False)
|
||||||
type = models.IntegerField('物料应用类型', default=SubprodctionMaterial.type_choices)
|
type = models.IntegerField('物料应用类型', default=SubprodctionMaterial.type_choices)
|
||||||
count = models.IntegerField('应出入数')
|
count = models.PositiveIntegerField('应出入数')
|
||||||
count_pick = models.IntegerField('实际领用数', default=0)
|
count_pick = models.PositiveIntegerField('实际领用数', default=0)
|
||||||
count_real = models.IntegerField('实际消耗/产出数', default=0)
|
count_real = models.PositiveIntegerField('实际消耗/产出数', default=0)
|
||||||
count_ok = models.IntegerField('合格数量', default=0)
|
count_ok = models.PositiveIntegerField('合格数量', default=0)
|
||||||
|
count_notok = models.PositiveIntegerField('不合格数量', default=0)
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,7 @@ class SubProductionPlanUpdateSerializer(serializers.ModelSerializer):
|
||||||
class GenSubPlanSerializer(serializers.Serializer):
|
class GenSubPlanSerializer(serializers.Serializer):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class SubProductionProgressSerializer(serializers.ModelSerializer):
|
|
||||||
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
|
||||||
class Meta:
|
|
||||||
model = SubProductionProgress
|
|
||||||
fields = '__all__'
|
|
||||||
|
|
||||||
class PickNeedSerializer(serializers.Serializer):
|
class PickNeedSerializer(serializers.Serializer):
|
||||||
warehouse = serializers.IntegerField(label="仓库ID")
|
warehouse = serializers.IntegerField(label="仓库ID")
|
||||||
|
|
@ -64,3 +60,10 @@ class SubproductionPlanSimpleSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SubProductionPlan
|
model = SubProductionPlan
|
||||||
fields = ['id', 'number']
|
fields = ['id', 'number']
|
||||||
|
|
||||||
|
class SubProductionProgressSerializer(serializers.ModelSerializer):
|
||||||
|
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
||||||
|
subproduction_plan_ = SubproductionPlanSimpleSerializer(source='subproduction_plan', read_only=True)
|
||||||
|
class Meta:
|
||||||
|
model = SubProductionProgress
|
||||||
|
fields = '__all__'
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
from django.db.models.aggregates import Sum
|
||||||
|
from apps.pm.models import ProductionPlan, SubProductionPlan
|
||||||
|
|
||||||
|
class PmService:
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update_plan_process_json(cls, plan:ProductionPlan):
|
||||||
|
"""
|
||||||
|
更新计划按工序统计字段
|
||||||
|
"""
|
||||||
|
ret = {}
|
||||||
|
subplans = SubProductionPlan.objects.filter(production_plan=plan, is_deleted=False)
|
||||||
|
qs = subplans.values('process', 'process__name', 'process__number').annotate(count=Sum('main_count'),
|
||||||
|
count_real=Sum('main_count_real'), count_ok=Sum('main_count_ok'), count_notok=Sum('main_count_notok'))
|
||||||
|
qs_list = list(qs)
|
||||||
|
for i in qs_list:
|
||||||
|
ret[i['process__number']] = {
|
||||||
|
'count':i['count'],
|
||||||
|
'count_real':i['count_real'],
|
||||||
|
'count_ok':i['count_ok'],
|
||||||
|
'count_notok':i['count_notok'],
|
||||||
|
'rate': round((i['count_ok']/(i['count_ok']+i['count_notok']))*100,2) if (i['count_ok']+i['count_notok']) > 0 else 0
|
||||||
|
}
|
||||||
|
plan.process_json = ret
|
||||||
|
plan.save()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2,6 +2,7 @@ from django.db.models.signals import post_save
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from apps.mtm.models import Material
|
from apps.mtm.models import Material
|
||||||
from apps.pm.models import SubProductionPlan, SubProductionProgress
|
from apps.pm.models import SubProductionPlan, SubProductionProgress
|
||||||
|
from apps.pm.services import PmService
|
||||||
|
|
||||||
@receiver(post_save, sender=SubProductionProgress)
|
@receiver(post_save, sender=SubProductionProgress)
|
||||||
def update_subplan_main(sender, instance, created, **kwargs):
|
def update_subplan_main(sender, instance, created, **kwargs):
|
||||||
|
|
@ -13,8 +14,10 @@ def update_subplan_main(sender, instance, created, **kwargs):
|
||||||
if created:
|
if created:
|
||||||
subplan.main_product = instance.material
|
subplan.main_product = instance.material
|
||||||
subplan.main_count = instance.count
|
subplan.main_count = instance.count
|
||||||
|
|
||||||
subplan.main_count_real = instance.count_real
|
subplan.main_count_real = instance.count_real
|
||||||
subplan.main_count_ok = instance.count_ok
|
subplan.main_count_ok = instance.count_ok
|
||||||
|
subplan.main_count_notok = instance.count_notok
|
||||||
if instance.count_ok >= instance.count and instance.count_ok > 0:
|
if instance.count_ok >= instance.count and instance.count_ok > 0:
|
||||||
subplan.state = SubProductionPlan.SUBPLAN_STATE_DONE
|
subplan.state = SubProductionPlan.SUBPLAN_STATE_DONE
|
||||||
elif instance.count_ok < instance.count and instance.count_ok > 0:
|
elif instance.count_ok < instance.count and instance.count_ok > 0:
|
||||||
|
|
@ -25,7 +28,12 @@ def update_subplan_main(sender, instance, created, **kwargs):
|
||||||
plan = subplan.production_plan
|
plan = subplan.production_plan
|
||||||
plan.count_real = subplan.main_count_real
|
plan.count_real = subplan.main_count_real
|
||||||
plan.count_ok = subplan.main_count_ok
|
plan.count_ok = subplan.main_count_ok
|
||||||
|
plan.count_notok = subplan.main_count_notok
|
||||||
plan.save()
|
plan.save()
|
||||||
|
# 更新计划工序统计字段
|
||||||
|
PmService.update_plan_process_json(subplan.production_plan)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ from apps.mtm.models import Step, SubProduction, SubprodctionMaterial, UsedStep
|
||||||
from apps.pm.filters import SubproductionProgressFilterSet
|
from apps.pm.filters import SubproductionProgressFilterSet
|
||||||
from apps.system.mixins import CreateUpdateModelAMixin
|
from apps.system.mixins import CreateUpdateModelAMixin
|
||||||
from apps.pm.serializers import GenSubPlanSerializer, PickNeedSerializer, PlanDestorySerializer, ProductionPlanCreateFromOrderSerializer, ProductionPlanSerializer, ResourceCalListSerializer, ResourceCalSerializer, SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer, SubProductionProgressSerializer
|
from apps.pm.serializers import GenSubPlanSerializer, PickNeedSerializer, PlanDestorySerializer, ProductionPlanCreateFromOrderSerializer, ProductionPlanSerializer, ResourceCalListSerializer, ResourceCalSerializer, SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer, SubProductionProgressSerializer
|
||||||
from rest_framework.mixins import CreateModelMixin, ListModelMixin, 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
|
||||||
|
|
@ -21,6 +21,7 @@ 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
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
def updateOrderPlanedCount(order):
|
def updateOrderPlanedCount(order):
|
||||||
|
|
@ -34,7 +35,7 @@ def updateOrderPlanedCount(order):
|
||||||
order.planed_count = planed_count
|
order.planed_count = planed_count
|
||||||
order.save()
|
order.save()
|
||||||
|
|
||||||
class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModelMixin, GenericViewSet):
|
class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModelMixin, RetrieveModelMixin, GenericViewSet):
|
||||||
"""
|
"""
|
||||||
生产计划
|
生产计划
|
||||||
"""
|
"""
|
||||||
|
|
@ -77,6 +78,7 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=GenSubPlanSerializer)
|
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=GenSubPlanSerializer)
|
||||||
|
@transaction.atomic
|
||||||
def gen_subplan(self, request, pk=None):
|
def gen_subplan(self, request, pk=None):
|
||||||
"""
|
"""
|
||||||
生成子计划
|
生成子计划
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ from rest_framework.decorators import action
|
||||||
from django.db.models import F
|
from django.db.models import F
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from apps.wf.models import Workflow
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
class CustomerViewSet(CreateUpdateCustomMixin, ModelViewSet):
|
class CustomerViewSet(CreateUpdateCustomMixin, ModelViewSet):
|
||||||
"""
|
"""
|
||||||
|
|
@ -168,6 +170,10 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C
|
||||||
FIFOItemProduct.objects.bulk_create(ipxs)
|
FIFOItemProduct.objects.bulk_create(ipxs)
|
||||||
# 更新成品库情况
|
# 更新成品库情况
|
||||||
ips.update(is_saled=True)
|
ips.update(is_saled=True)
|
||||||
|
# 更新动态产品表情况
|
||||||
|
from apps.wpm.models import WProduct
|
||||||
|
WProduct.objects.filter(iproduct_wproduct__sale_iproduct__sale=obj).update(
|
||||||
|
act_state=WProduct.WPR_ACT_STATE_SELLED)
|
||||||
# 更新库存
|
# 更新库存
|
||||||
update_inm(fifo)
|
update_inm(fifo)
|
||||||
# 变更审核状态
|
# 变更审核状态
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-23 02:06
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('wf', '0019_auto_20211221_0923'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customfield',
|
||||||
|
name='is_hidden',
|
||||||
|
field=models.BooleanField(default=False, help_text='可用于携带不需要用户查看的信息', verbose_name='是否隐藏'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='customfield',
|
||||||
|
name='field_choice',
|
||||||
|
field=models.JSONField(blank=True, default=list, help_text='选项值,格式为list, 例["id":1, "name":"张三"]', verbose_name='选项值'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='customfield',
|
||||||
|
name='field_type',
|
||||||
|
field=models.CharField(choices=[('string', '字符串'), ('int', '整型'), ('float', '浮点'), ('boolean', '布尔'), ('date', '日期'), ('datetime', '日期时间'), ('radio', '单选'), ('checkbox', '多选'), ('select', '单选下拉'), ('selects', '多选下拉'), ('cascader', '单选级联'), ('cascaders', '多选级联'), ('select_dg', '弹框单选'), ('select_dgs', '弹框多选'), ('textarea', '文本域'), ('file', '附件')], help_text='5.字符串,10.整形,15.浮点型,20.布尔,25.日期,30.日期时间,35.单选框,40.多选框,45.下拉列表,50.多选下拉列表,55.文本域,60.用户名, 70.多选的用户名, 80.附件(只保存路径,多个使用逗号隔开)', max_length=50, verbose_name='类型'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='customfield',
|
||||||
|
name='label',
|
||||||
|
field=models.CharField(default='', help_text='处理特殊逻辑使用', max_length=1000, verbose_name='标签'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='workflow',
|
||||||
|
name='title_template',
|
||||||
|
field=models.CharField(blank=True, default='{title}', help_text='工单字段的值可以作为参数写到模板中,格式如:你有一个待办工单:{title}', max_length=50, null=True, verbose_name='标题模板'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-24 06:26
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('wf', '0020_auto_20211223_1006'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='customfield',
|
||||||
|
name='description',
|
||||||
|
field=models.CharField(blank=True, help_text='字段的描述信息,可用于显示在字段的下方对该字段的详细描述', max_length=100, null=True, verbose_name='描述'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='customfield',
|
||||||
|
name='field_template',
|
||||||
|
field=models.TextField(blank=True, help_text='文本域类型字段前端显示时可以将此内容作为字段的placeholder', null=True, verbose_name='文本域模板'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='customfield',
|
||||||
|
name='field_type',
|
||||||
|
field=models.CharField(choices=[('string', '字符串'), ('int', '整型'), ('float', '浮点'), ('boolean', '布尔'), ('date', '日期'), ('datetime', '日期时间'), ('radio', '单选'), ('checkbox', '多选'), ('select', '单选下拉'), ('selects', '多选下拉'), ('cascader', '单选级联'), ('cascaders', '多选级联'), ('select_dg', '弹框单选'), ('select_dgs', '弹框多选'), ('textarea', '文本域'), ('file', '附件')], help_text='string, int, float, date, datetime, radio, checkbox, select, selects, cascader, cascaders, cascader, cascaders,textarea, file', max_length=50, verbose_name='类型'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='customfield',
|
||||||
|
name='placeholder',
|
||||||
|
field=models.CharField(blank=True, help_text='用户工单详情表单中作为字段的占位符显示', max_length=100, null=True, verbose_name='占位符'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-27 01:48
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('wf', '0021_auto_20211224_1426'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='customfield',
|
||||||
|
name='is_hidden',
|
||||||
|
field=models.BooleanField(default=False, help_text='可用于携带不需要用户查看的字段信息', verbose_name='是否隐藏'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-27 05:18
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('wf', '0022_alter_customfield_is_hidden'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='customfield',
|
||||||
|
name='field_type',
|
||||||
|
field=models.CharField(choices=[('string', '字符串'), ('int', '整型'), ('float', '浮点'), ('boolean', '布尔'), ('date', '日期'), ('datetime', '日期时间'), ('radio', '单选'), ('checkbox', '多选'), ('select', '单选下拉'), ('selects', '多选下拉'), ('cascader', '单选级联'), ('cascaders', '多选级联'), ('select_dg', '弹框单选'), ('select_dgs', '弹框多选'), ('textarea', '文本域'), ('file', '附件')], help_text='string, int, float, date, datetime, radio, checkbox, select, selects, cascader, cascaders, select_dg, select_dgs,textarea, file', max_length=50, verbose_name='类型'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='customfield',
|
||||||
|
name='label',
|
||||||
|
field=models.CharField(default='', help_text='处理特殊逻辑使用,比如sys_user用于获取用户作为选项', max_length=1000, verbose_name='标签'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -150,26 +150,32 @@ class CustomField(CommonAModel):
|
||||||
('checkbox', '多选'),
|
('checkbox', '多选'),
|
||||||
('select', '单选下拉'),
|
('select', '单选下拉'),
|
||||||
('selects', '多选下拉'),
|
('selects', '多选下拉'),
|
||||||
|
('cascader', '单选级联'),
|
||||||
|
('cascaders', '多选级联'),
|
||||||
|
('select_dg', '弹框单选'),
|
||||||
|
('select_dgs', '弹框多选'),
|
||||||
('textarea', '文本域'),
|
('textarea', '文本域'),
|
||||||
('selectuser', '单选用户'),
|
('file', '附件')
|
||||||
('selectusers', '多选用户'),
|
|
||||||
('file', '附件'),
|
|
||||||
('draw', '绘图')
|
|
||||||
)
|
)
|
||||||
workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE, verbose_name='所属工作流')
|
workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE, verbose_name='所属工作流')
|
||||||
field_type = models.CharField('类型', max_length=50, choices=field_type_choices, help_text='5.字符串,10.整形,15.浮点型,20.布尔,25.日期,30.日期时间,35.单选框,40.多选框,45.下拉列表,50.多选下拉列表,55.文本域,60.用户名, 70.多选的用户名, 80.附件(只保存路径,多个使用逗号隔开)')
|
field_type = models.CharField('类型', max_length=50, choices=field_type_choices,
|
||||||
|
help_text='string, int, float, date, datetime, radio, checkbox, select, selects, cascader, cascaders, select_dg, select_dgs,textarea, file')
|
||||||
field_key = models.CharField('字段标识', max_length=50, help_text='字段类型请尽量特殊,避免与系统中关键字冲突')
|
field_key = models.CharField('字段标识', max_length=50, help_text='字段类型请尽量特殊,避免与系统中关键字冲突')
|
||||||
field_name = models.CharField('字段名称', max_length=50)
|
field_name = models.CharField('字段名称', max_length=50)
|
||||||
sort = models.IntegerField('排序', default=0, help_text='工单基础字段在表单中排序为:流水号0,标题20,状态id40,状态名41,创建人80,创建时间100,更新时间120.前端展示工单信息的表单可以根据这个id顺序排列')
|
sort = models.IntegerField('排序', default=0, help_text='工单基础字段在表单中排序为:流水号0,标题20,状态id40,状态名41,创建人80,创建时间100,更新时间120.前端展示工单信息的表单可以根据这个id顺序排列')
|
||||||
default_value = models.CharField('默认值', null=True, blank=True, max_length=100, help_text='前端展示时,可以将此内容作为表单中的该字段的默认值')
|
default_value = models.CharField('默认值', null=True, blank=True, max_length=100, help_text='前端展示时,可以将此内容作为表单中的该字段的默认值')
|
||||||
description = models.CharField('描述', max_length=100, blank=True, default='', help_text='字段的描述信息,可用于显示在字段的下方对该字段的详细描述')
|
description = models.CharField('描述', max_length=100, blank=True, null=True, help_text='字段的描述信息,可用于显示在字段的下方对该字段的详细描述')
|
||||||
placeholder = models.CharField('占位符', max_length=100, blank=True, default='', help_text='用户工单详情表单中作为字段的占位符显示')
|
placeholder = models.CharField('占位符', max_length=100, blank=True, null=True, help_text='用户工单详情表单中作为字段的占位符显示')
|
||||||
field_template = models.TextField('文本域模板', default='', blank=True, help_text='文本域类型字段前端显示时可以将此内容作为字段的placeholder')
|
field_template = models.TextField('文本域模板', null=True, blank=True, help_text='文本域类型字段前端显示时可以将此内容作为字段的placeholder')
|
||||||
boolean_field_display = models.JSONField('布尔类型显示名', default=dict, blank=True,
|
boolean_field_display = models.JSONField('布尔类型显示名', default=dict, blank=True,
|
||||||
help_text='当为布尔类型时候,可以支持自定义显示形式。{"1":"是","0":"否"}或{"1":"需要","0":"不需要"},注意数字也需要引号')
|
help_text='当为布尔类型时候,可以支持自定义显示形式。{"1":"是","0":"否"}或{"1":"需要","0":"不需要"},注意数字也需要引号')
|
||||||
field_choice = models.JSONField('radio、checkbox、select的选项', default=dict, blank=True,
|
|
||||||
help_text='radio,checkbox,select,multiselect类型可供选择的选项,格式为json如:{"1":"中国", "2":"美国"},注意数字也需要引号')
|
field_choice = models.JSONField('选项值', default=list, blank=True,
|
||||||
label = models.JSONField('标签', blank=True, default=dict, help_text='自定义标签,json格式,调用方可根据标签自行处理特殊场景逻辑,loonflow只保存文本内容')
|
help_text='选项值,格式为list, 例["id":1, "name":"张三"]')
|
||||||
|
|
||||||
|
label = models.CharField('标签', max_length=1000, default='', help_text='处理特殊逻辑使用,比如sys_user用于获取用户作为选项')
|
||||||
|
# hook = models.CharField('hook', max_length=1000, default='', help_text='获取下拉选项用于动态选项值')
|
||||||
|
is_hidden = models.BooleanField('是否隐藏', default=False, help_text='可用于携带不需要用户查看的字段信息')
|
||||||
|
|
||||||
class Ticket(CommonBModel):
|
class Ticket(CommonBModel):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -38,12 +38,33 @@ class TransitionSerializer(serializers.ModelSerializer):
|
||||||
queryset = queryset.select_related('source_state','destination_state')
|
queryset = queryset.select_related('source_state','destination_state')
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
class AllField(serializers.Field):
|
||||||
|
def to_representation(self, value):
|
||||||
|
return value
|
||||||
|
|
||||||
|
def to_internal_value(self, data):
|
||||||
|
return data
|
||||||
|
|
||||||
|
class FieldChoiceSerializer(serializers.Serializer):
|
||||||
|
id = AllField(label='ID')
|
||||||
|
name = serializers.CharField(label='名称')
|
||||||
|
|
||||||
|
|
||||||
class CustomFieldSerializer(serializers.ModelSerializer):
|
class CustomFieldSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CustomField
|
model = CustomField
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
class CustomFieldCreateUpdateSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
|
field_choice = FieldChoiceSerializer(label='选项列表', many=True, required=False)
|
||||||
|
class Meta:
|
||||||
|
model = CustomField
|
||||||
|
fields = ['workflow', 'field_type', 'field_key', 'field_name',
|
||||||
|
'sort', 'default_value', 'description', 'placeholder', 'field_template',
|
||||||
|
'boolean_field_display', 'field_choice', 'label', 'is_hidden']
|
||||||
|
|
||||||
|
|
||||||
class TicketSimpleSerializer(serializers.ModelSerializer):
|
class TicketSimpleSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Ticket
|
model = Ticket
|
||||||
|
|
@ -107,8 +128,29 @@ class TicketDetailSerializer(serializers.ModelSerializer):
|
||||||
key = i['field_key']
|
key = i['field_key']
|
||||||
i['field_state'] = state_fields.get(key, 1)
|
i['field_state'] = state_fields.get(key, 1)
|
||||||
i['field_value'] = ticket_data.get(key, None)
|
i['field_value'] = ticket_data.get(key, None)
|
||||||
|
i['field_display'] = i['field_value'] # 该字段是用于查看详情直接展示
|
||||||
|
if i['field_value']:
|
||||||
|
if 'sys_user' in i['label']:
|
||||||
|
if isinstance(i['field_value'], list):
|
||||||
|
i['field_display'] = ','.join(list(User.objects.filter(id__in=i['field_value']).values_list('name', flat=True)))
|
||||||
|
else:
|
||||||
|
i['field_display'] = User.objects.get(id=i['field_value']).name
|
||||||
|
elif i['field_type'] in ['radio', 'select']:
|
||||||
|
for m in i['field_choice']:
|
||||||
|
if m['id'] == i['field_value']:
|
||||||
|
i['field_display'] = m['name']
|
||||||
|
elif i['field_type'] in ['checkbox', 'selects']:
|
||||||
|
d_list = []
|
||||||
|
for m in i['field_choice']:
|
||||||
|
if m['id'] in i['field_value']:
|
||||||
|
d_list.append(m['name'])
|
||||||
|
i['field_display'] = ','.join(d_list)
|
||||||
return all_fields_l
|
return all_fields_l
|
||||||
|
|
||||||
|
def filter_display(self, item, field_value):
|
||||||
|
if item['id'] == field_value:
|
||||||
|
return
|
||||||
|
|
||||||
class TicketFlowSerializer(serializers.ModelSerializer):
|
class TicketFlowSerializer(serializers.ModelSerializer):
|
||||||
participant_ = UserSimpleSerializer(source='participant', read_only=True)
|
participant_ = UserSimpleSerializer(source='participant', read_only=True)
|
||||||
state_ = StateSimpleSerializer(source='state', read_only=True)
|
state_ = StateSimpleSerializer(source='state', read_only=True)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ from django.core.exceptions import AppRegistryNotReady
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
|
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
|
||||||
from apps.wf.serializers import CustomFieldSerializer, StateSerializer, TicketAddNodeEndSerializer, TicketAddNodeSerializer, TicketCloseSerializer, TicketCreateSerializer, TicketDestorySerializer, TicketFlowSerializer, TicketFlowSimpleSerializer, TicketHandleSerializer, TicketRetreatSerializer, TicketSerializer, TransitionSerializer, WorkflowSerializer, TicketListSerializer, TicketDetailSerializer
|
from apps.wf.serializers import CustomFieldCreateUpdateSerializer, CustomFieldSerializer, StateSerializer, TicketAddNodeEndSerializer, TicketAddNodeSerializer, TicketCloseSerializer, TicketCreateSerializer, TicketDestorySerializer, TicketFlowSerializer, TicketFlowSimpleSerializer, TicketHandleSerializer, TicketRetreatSerializer, TicketSerializer, TransitionSerializer, WorkflowSerializer, TicketListSerializer, TicketDetailSerializer
|
||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||||
from rest_framework.decorators import action, api_view
|
from rest_framework.decorators import action, api_view
|
||||||
|
|
@ -111,6 +111,11 @@ class CustomFieldViewSet(CreateModelMixin, UpdateModelMixin, RetrieveModelMixin,
|
||||||
filterset_fields = ['workflow', 'field_type']
|
filterset_fields = ['workflow', 'field_type']
|
||||||
ordering = ['sort']
|
ordering = ['sort']
|
||||||
|
|
||||||
|
def get_serializer_class(self):
|
||||||
|
if self.action in ['create', 'update']:
|
||||||
|
return CustomFieldCreateUpdateSerializer
|
||||||
|
return super().get_serializer_class()
|
||||||
|
|
||||||
class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin, ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin, ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
||||||
perms_map = {'*':'*'}
|
perms_map = {'*':'*'}
|
||||||
queryset = Ticket.objects.all()
|
queryset = Ticket.objects.all()
|
||||||
|
|
@ -133,7 +138,7 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin
|
||||||
return super().get_serializer_class()
|
return super().get_serializer_class()
|
||||||
|
|
||||||
def filter_queryset(self, queryset):
|
def filter_queryset(self, queryset):
|
||||||
if not self.request.query_params.get('category', None):
|
if not self.detail and not self.request.query_params.get('category', None):
|
||||||
raise APIException('请指定查询分类')
|
raise APIException('请指定查询分类')
|
||||||
return super().filter_queryset(queryset)
|
return super().filter_queryset(queryset)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ class WMaterialFilterSet(filters.FilterSet):
|
||||||
|
|
||||||
class WProductFilterSet(filters.FilterSet):
|
class WProductFilterSet(filters.FilterSet):
|
||||||
tag = filters.CharFilter(method='filter_tag')
|
tag = filters.CharFilter(method='filter_tag')
|
||||||
|
production_plan = filters.NumberFilter(field_name='subproduction_plan__production_plan')
|
||||||
class Meta:
|
class Meta:
|
||||||
model = WProduct
|
model = WProduct
|
||||||
fields = ['step', 'subproduction_plan', 'material', 'step__process', 'act_state', 'material__type']
|
fields = ['step', 'subproduction_plan', 'material', 'step__process', 'act_state', 'material__type']
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-27 01:48
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('wpm', '0037_wproduct_scrap_reason'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='wproduct',
|
||||||
|
name='ng_sign',
|
||||||
|
field=models.PositiveSmallIntegerField(blank=True, choices=[(10, '返工'), (20, '返修'), (30, '报废'), (40, '让步接收'), (50, '偏离许可'), (60, '降级使用'), (70, '退回供方'), (80, '召回')], null=True, verbose_name='不合格标记'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='wproduct',
|
||||||
|
name='act_state',
|
||||||
|
field=models.IntegerField(choices=[(6, '待复检'), (8, '操作准备中'), (10, '操作进行中'), (20, '待检验'), (26, '待夹层检验'), (30, '已合格'), (40, '已入库'), (50, '不合格'), (60, '待成品检验'), (70, '已报废'), (80, '已售出')], default=0, verbose_name='进行状态'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='wprouctticket',
|
||||||
|
name='decision',
|
||||||
|
field=models.PositiveSmallIntegerField(blank=True, choices=[(10, '返工'), (20, '返修'), (30, '报废'), (40, '让步接收'), (50, '偏离许可'), (60, '降级使用'), (70, '退回供方'), (80, '召回')], null=True, verbose_name='最终决定'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-28 06:17
|
||||||
|
|
||||||
|
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 = [
|
||||||
|
('inm', '0024_auto_20211227_0948'),
|
||||||
|
('qm', '0022_auto_20211216_1401'),
|
||||||
|
('mtm', '0042_alter_recordformfield_field_type'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('pm', '0019_alter_productionplan_process_json'),
|
||||||
|
('wf', '0023_auto_20211227_1318'),
|
||||||
|
('wpm', '0038_auto_20211227_0948'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='wprouctticket',
|
||||||
|
name='step',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.step', verbose_name='所在步骤/发现步骤'),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='WproductFlow',
|
||||||
|
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='删除标记')),
|
||||||
|
('number', models.CharField(blank=True, max_length=50, null=True, unique=True, verbose_name='物品编号')),
|
||||||
|
('act_state', models.IntegerField(choices=[(6, '待复检'), (8, '操作准备中'), (10, '操作进行中'), (20, '待检验'), (26, '待夹层检验'), (30, '已合格'), (40, '已入库'), (50, '不合格'), (60, '待成品检验'), (70, '已报废'), (80, '已售出')], default=0, verbose_name='进行状态')),
|
||||||
|
('is_hidden', models.BooleanField(default=False, verbose_name='是否隐藏')),
|
||||||
|
('remark', models.CharField(blank=True, max_length=200, null=True, verbose_name='备注')),
|
||||||
|
('scrap_reason', models.IntegerField(blank=True, choices=[(10, '气泡'), (20, '破点'), (30, '划伤'), (40, '其他')], null=True, verbose_name='报废原因')),
|
||||||
|
('ng_sign', models.PositiveSmallIntegerField(blank=True, choices=[(10, '返工'), (20, '返修'), (30, '报废'), (40, '让步接收'), (50, '偏离许可'), (60, '降级使用'), (70, '退回供方'), (80, '召回')], null=True, verbose_name='不合格标记')),
|
||||||
|
('is_lastlog', models.BooleanField(default=True, verbose_name='是否该子计划下的最后一条日志')),
|
||||||
|
('child', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='wpm.wproductflow')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wproductflow_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='所属物料状态')),
|
||||||
|
('operation', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='wpm.operation', verbose_name='当前操作')),
|
||||||
|
('pre_step', models.ForeignKey(blank=True, help_text='已执行完的步骤', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wl_pre_step', to='mtm.step', verbose_name='已执行到')),
|
||||||
|
('step', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wl_step', to='mtm.step', verbose_name='所在步骤')),
|
||||||
|
('subproduction_plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pm.subproductionplan', verbose_name='当前子生产计划')),
|
||||||
|
('test', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='qm.testrecord', verbose_name='当前检验')),
|
||||||
|
('ticket', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='wf.ticket', verbose_name='当前工单')),
|
||||||
|
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wproductflow_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
('warehouse', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='inm.warehouse', verbose_name='所在仓库')),
|
||||||
|
('wproduct', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='wpm.wproduct', verbose_name='关联产品')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-28 07:48
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('wpm', '0039_auto_20211228_1417'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='wproductflow',
|
||||||
|
name='number',
|
||||||
|
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='物品编号'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -36,6 +36,7 @@ class WProduct(CommonAModel):
|
||||||
WPR_ACT_STATE_NOTOK = 50
|
WPR_ACT_STATE_NOTOK = 50
|
||||||
WPR_ACT_STATE_TOFINALTEST = 60
|
WPR_ACT_STATE_TOFINALTEST = 60
|
||||||
WPR_ACT_STATE_SCRAP = 70
|
WPR_ACT_STATE_SCRAP = 70
|
||||||
|
WPR_ACT_STATE_SELLED = 80
|
||||||
act_state_choices=(
|
act_state_choices=(
|
||||||
(WPR_ACT_STATE_TORETEST, '待复检'),
|
(WPR_ACT_STATE_TORETEST, '待复检'),
|
||||||
(WPR_ACT_STATE_DOWAIT, '操作准备中'),
|
(WPR_ACT_STATE_DOWAIT, '操作准备中'),
|
||||||
|
|
@ -46,7 +47,8 @@ class WProduct(CommonAModel):
|
||||||
(WPR_ACT_STATE_INM, '已入库'),
|
(WPR_ACT_STATE_INM, '已入库'),
|
||||||
(WPR_ACT_STATE_NOTOK, '不合格'),
|
(WPR_ACT_STATE_NOTOK, '不合格'),
|
||||||
(WPR_ACT_STATE_TOFINALTEST, '待成品检验'),
|
(WPR_ACT_STATE_TOFINALTEST, '待成品检验'),
|
||||||
(WPR_ACT_STATE_SCRAP, '已报废')
|
(WPR_ACT_STATE_SCRAP, '已报废'),
|
||||||
|
(WPR_ACT_STATE_SELLED, '已售出'),
|
||||||
)
|
)
|
||||||
SCRAP_REASON_QIPAO = 10
|
SCRAP_REASON_QIPAO = 10
|
||||||
SCRAP_REASON_PODIAN = 20
|
SCRAP_REASON_PODIAN = 20
|
||||||
|
|
@ -58,6 +60,26 @@ class WProduct(CommonAModel):
|
||||||
(30, '划伤'),
|
(30, '划伤'),
|
||||||
(40, '其他')
|
(40, '其他')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
NG_BACK_WORK = 10
|
||||||
|
NG_BACK_FIX = 20
|
||||||
|
NG_SCRAP = 30
|
||||||
|
NG_ACCEPT = 40
|
||||||
|
NG_PERMIT = 50
|
||||||
|
NG_DOWN = 60
|
||||||
|
NG_BACK_FROM = 70
|
||||||
|
NG_RECALL = 80
|
||||||
|
|
||||||
|
ng_choices = (
|
||||||
|
(NG_BACK_WORK, '返工'),
|
||||||
|
(NG_BACK_FIX, '返修'),
|
||||||
|
(NG_SCRAP, '报废'),
|
||||||
|
(NG_ACCEPT, '让步接收'),
|
||||||
|
(NG_PERMIT, '偏离许可'),
|
||||||
|
(NG_DOWN, '降级使用'),
|
||||||
|
(NG_BACK_FROM, '退回供方'),
|
||||||
|
(NG_RECALL, '召回')
|
||||||
|
)
|
||||||
number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50)
|
number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50)
|
||||||
material = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
|
material = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
|
||||||
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='w_pre_step')
|
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='w_pre_step')
|
||||||
|
|
@ -69,6 +91,9 @@ class WProduct(CommonAModel):
|
||||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE, related_name='wproduct_subplan')
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE, related_name='wproduct_subplan')
|
||||||
|
|
||||||
scrap_reason = models.IntegerField('报废原因', choices=scrap_reason_choices, null=True, blank=True)
|
scrap_reason = models.IntegerField('报废原因', choices=scrap_reason_choices, null=True, blank=True)
|
||||||
|
|
||||||
|
ng_sign = models.PositiveSmallIntegerField('不合格标记', choices=ng_choices, null=True, blank=True)
|
||||||
|
|
||||||
warehouse = models.ForeignKey(WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)
|
warehouse = models.ForeignKey(WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
operation = models.ForeignKey('wpm.operation', verbose_name='当前操作',
|
operation = models.ForeignKey('wpm.operation', verbose_name='当前操作',
|
||||||
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_operation')
|
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_operation')
|
||||||
|
|
@ -89,14 +114,43 @@ class WprouctTicket(CommonAModel):
|
||||||
"""
|
"""
|
||||||
玻璃审批工单
|
玻璃审批工单
|
||||||
"""
|
"""
|
||||||
|
|
||||||
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
||||||
wproduct = models.ForeignKey(WProduct, verbose_name='关联产品', on_delete=models.CASCADE)
|
wproduct = models.ForeignKey(WProduct, verbose_name='关联产品', on_delete=models.CASCADE)
|
||||||
material = models.ForeignKey(Material, verbose_name='所在物料状态', on_delete=models.CASCADE)
|
material = models.ForeignKey(Material, verbose_name='所在物料状态', on_delete=models.CASCADE)
|
||||||
step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE)
|
step = models.ForeignKey(Step, verbose_name='所在步骤/发现步骤', on_delete=models.CASCADE)
|
||||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='所在子生产计划', on_delete=models.CASCADE)
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='所在子生产计划', on_delete=models.CASCADE)
|
||||||
|
|
||||||
ticket = models.ForeignKey('wf.ticket', verbose_name='关联工单', on_delete=models.CASCADE, related_name='wt_ticket')
|
ticket = models.ForeignKey('wf.ticket', verbose_name='关联工单', on_delete=models.CASCADE, related_name='wt_ticket')
|
||||||
decision = models.CharField('最终决定', null=True, blank=True, max_length=100)
|
decision = models.PositiveSmallIntegerField('最终决定', choices=WProduct.ng_choices, null=True, blank=True)
|
||||||
|
|
||||||
|
class WproductFlow(CommonAModel):
|
||||||
|
"""
|
||||||
|
动态产品表日志
|
||||||
|
"""
|
||||||
|
wproduct = models.ForeignKey(WProduct, on_delete=models.CASCADE, verbose_name='关联产品', null=True, blank=True)
|
||||||
|
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
||||||
|
material = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
|
||||||
|
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='wl_pre_step')
|
||||||
|
step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True, related_name='wl_step')
|
||||||
|
act_state = models.IntegerField('进行状态', default=0, choices=WProduct.act_state_choices)
|
||||||
|
is_hidden = models.BooleanField('是否隐藏', default=False)
|
||||||
|
child = models.ForeignKey('self', blank=True, null=True, on_delete=models.CASCADE)
|
||||||
|
remark = models.CharField('备注', max_length=200, null=True, blank=True)
|
||||||
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
scrap_reason = models.IntegerField('报废原因', choices= WProduct.scrap_reason_choices, null=True, blank=True)
|
||||||
|
ng_sign = models.PositiveSmallIntegerField('不合格标记', choices= WProduct.ng_choices, null=True, blank=True)
|
||||||
|
|
||||||
|
warehouse = models.ForeignKey(WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
|
operation = models.ForeignKey('wpm.operation', verbose_name='当前操作',
|
||||||
|
on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
|
test = models.ForeignKey('qm.testrecord', verbose_name='当前检验',
|
||||||
|
on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
|
ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单',
|
||||||
|
on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
|
is_lastlog = models.BooleanField('是否该子计划下的最后一条日志', default=True)
|
||||||
|
|
||||||
|
|
||||||
class Pick(CommonADModel):
|
class Pick(CommonADModel):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -382,6 +382,7 @@ class OperationMaterialCreate2Serailizer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class OperationMaterialCreate2ListSerailizer(serializers.ListSerializer):
|
class OperationMaterialCreate2ListSerailizer(serializers.ListSerializer):
|
||||||
child=OperationMaterialCreate2Serailizer()
|
child=OperationMaterialCreate2Serailizer()
|
||||||
|
|
||||||
class OperationMaterialCreate3Serializer(serializers.ModelSerializer):
|
class OperationMaterialCreate3Serializer(serializers.ModelSerializer):
|
||||||
material = serializers.PrimaryKeyRelatedField(required=True, queryset=Material.objects.all())
|
material = serializers.PrimaryKeyRelatedField(required=True, queryset=Material.objects.all())
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
|
from django.utils import timezone
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
|
from django.db.models.expressions import F
|
||||||
from apps.pm.models import SubProductionPlan, SubProductionProgress
|
from apps.pm.models import SubProductionPlan, SubProductionProgress
|
||||||
from apps.mtm.models import Material, Step, SubprodctionMaterial
|
from apps.mtm.models import Material, Step, SubprodctionMaterial
|
||||||
from apps.qm.models import TestRecord
|
from apps.qm.models import TestRecord
|
||||||
from apps.system.models import User
|
from apps.system.models import User
|
||||||
from apps.wpm.models import WProduct
|
from apps.wf.models import State, TicketFlow, Transition
|
||||||
|
from apps.wpm.models import WProduct, WproductFlow, WprouctTicket
|
||||||
from utils.tools import ranstr
|
from utils.tools import ranstr
|
||||||
class WpmServies(object):
|
class WpmServies(object):
|
||||||
|
|
||||||
|
|
@ -46,21 +50,72 @@ class WpmServies(object):
|
||||||
if is_testok:
|
if is_testok:
|
||||||
if wproduct.act_state == WProduct.WPR_ACT_STATE_TORETEST: # 复检
|
if wproduct.act_state == WProduct.WPR_ACT_STATE_TORETEST: # 复检
|
||||||
wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
|
wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
|
||||||
|
|
||||||
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and wproduct.material.type == Material.MA_TYPE_GOOD: # 成品检验
|
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and wproduct.material.type == Material.MA_TYPE_GOOD: # 成品检验
|
||||||
wproduct.act_state = WProduct.WPR_ACT_STATE_TOFINALTEST
|
wproduct.act_state = WProduct.WPR_ACT_STATE_TOFINALTEST
|
||||||
else:
|
else:
|
||||||
wproduct.act_state = WProduct.WPR_ACT_STATE_OK
|
wproduct.act_state = WProduct.WPR_ACT_STATE_OK
|
||||||
if wproduct.number is None: # 产生半成品编号
|
if wproduct.number is None: # 产生半成品编号
|
||||||
wproduct.number = 'WP'+ranstr(7)
|
wproduct.number = 'WP'+ranstr(7)
|
||||||
# 更新子计划状态
|
|
||||||
# 更新子计划主产品数
|
# 去除ng_sign
|
||||||
instance = SubProductionProgress.objects.get(subproduction_plan=wproduct.subproduction_plan,
|
if wproduct.ng_sign:
|
||||||
is_main=True, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
wt = WprouctTicket.objects.order_by('id').last() #取最后的工单
|
||||||
instance.count_ok = instance.count_ok + 1 # 这个地方可能会有问题
|
if wt.step.process == test.step.process:
|
||||||
instance.save()
|
wproduct.ng_sign = None
|
||||||
|
ticket = wt.ticket
|
||||||
|
ticket_data = wt.ticket_data
|
||||||
|
ticket_data['retest_result'] = 1
|
||||||
|
ticket.update_by = user
|
||||||
|
ticket.save()
|
||||||
|
# 创建处理日志
|
||||||
|
TicketFlow.objects.create(ticket=ticket, state=ticket.state,
|
||||||
|
participant_type=State.PARTICIPANT_TYPE_PERSONAL,
|
||||||
|
intervene_type=0,
|
||||||
|
participant=user)
|
||||||
|
|
||||||
|
|
||||||
|
# 更新子计划相关进度
|
||||||
|
cls.update_subproduction_progress_main(sp=wproduct.subproduction_plan)
|
||||||
else:# 如果不合格
|
else:# 如果不合格
|
||||||
wproduct.act_state = WProduct.WPR_ACT_STATE_NOTOK
|
wproduct.act_state = WProduct.WPR_ACT_STATE_NOTOK
|
||||||
# 需要走不合格品审理的工单
|
# 需要走不合格品审理的工单
|
||||||
|
# 如果已经是返工返修的产品
|
||||||
|
if wproduct.ng_sign:
|
||||||
|
wt = WprouctTicket.objects.order_by('id').last() #取最后的工单
|
||||||
|
if wt.step.process == test.step.process:
|
||||||
|
ticket = wt.ticket
|
||||||
|
ticket_data = wt.ticket_data
|
||||||
|
ticket_data['retest_result'] = 0
|
||||||
|
ticket.update_by = user
|
||||||
|
ticket.save()
|
||||||
|
# 创建处理日志
|
||||||
|
TicketFlow.objects.create(ticket=ticket, state=ticket.state,
|
||||||
|
participant_type=State.PARTICIPANT_TYPE_PERSONAL,
|
||||||
|
intervene_type=0,
|
||||||
|
participant=user)
|
||||||
|
|
||||||
|
|
||||||
wproduct.update_by = user
|
wproduct.update_by = user
|
||||||
|
wproduct.update_time = timezone.now()
|
||||||
wproduct.test = None
|
wproduct.test = None
|
||||||
wproduct.save()
|
wproduct.save()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update_subproduction_progress_main(cls, sp:SubProductionPlan):
|
||||||
|
"""
|
||||||
|
根据产品变动日志更新生产进度
|
||||||
|
"""
|
||||||
|
objs = WproductFlow.objects.filter(subproduction_plan=sp, is_lastlog=True)
|
||||||
|
count_ok = objs.filter(act_state__in=[WProduct.WPR_ACT_STATE_INM,
|
||||||
|
WProduct.WPR_ACT_STATE_OK, WProduct.WPR_ACT_STATE_SELLED]).count()
|
||||||
|
count_notok = objs.filter(act_state__in=[WProduct.WPR_ACT_STATE_NOTOK, WProduct.WPR_ACT_STATE_SCRAP]).count()
|
||||||
|
count_real = objs.exclude(act_state__in=[WProduct.WPR_ACT_STATE_TORETEST,
|
||||||
|
WProduct.WPR_ACT_STATE_DOWAIT, WProduct.WPR_ACT_STATE_DOING]).count()
|
||||||
|
ins = SubProductionProgress.objects.filter(subproduction_plan=sp,
|
||||||
|
is_main=True, type=SubprodctionMaterial.SUB_MA_TYPE_OUT).first()
|
||||||
|
if ins:
|
||||||
|
ins.count_ok = count_ok
|
||||||
|
ins.count_notok = count_notok
|
||||||
|
ins.count_real = count_real
|
||||||
|
ins.save()
|
||||||
|
|
@ -1,9 +1,14 @@
|
||||||
|
from django.db.models.expressions import F
|
||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
|
from apps.mtm.models import Step, SubprodctionMaterial
|
||||||
|
from apps.pm.models import SubProductionPlan, SubProductionProgress
|
||||||
from apps.qm.models import TestRecord
|
from apps.qm.models import TestRecord
|
||||||
from apps.wf.models import Ticket
|
from apps.wf.models import Ticket
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
from rest_framework import exceptions
|
||||||
from apps.wpm.models import WProduct, WprouctTicket
|
from apps.wpm.models import WProduct, WproductFlow, WprouctTicket
|
||||||
|
from apps.wpm.models import OperationWproduct
|
||||||
|
from apps.wpm.services import WpmServies
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=Ticket)
|
@receiver(post_save, sender=Ticket)
|
||||||
|
|
@ -41,20 +46,53 @@ def handleTicket(sender, instance, created, **kwargs):
|
||||||
执行操作决定
|
执行操作决定
|
||||||
"""
|
"""
|
||||||
ticket_data = instance.ticket_data
|
ticket_data = instance.ticket_data
|
||||||
wt = instance.wt_ticket
|
wt = WprouctTicket.objects.get(ticket=instance)
|
||||||
wp = wt.wproduct
|
wp = wt.wproduct
|
||||||
|
decision = WProduct.NG_BACK_WORK
|
||||||
|
|
||||||
if 'decision_1' in ticket_data and ticket_data['decision_1']:
|
if 'decision_1' in ticket_data and ticket_data['decision_1']:
|
||||||
wt.decision = ticket_data['decision_1']
|
decision = ticket_data['decision_1']
|
||||||
if ticket_data['decision_1'] in ['返工', '返修']:
|
|
||||||
pass
|
|
||||||
elif ticket_data['decision_1'] in ['让步接收']:
|
|
||||||
wp.act_state = WProduct.WPR_ACT_STATE_OK
|
|
||||||
elif 'decision_2' in ticket_data and ticket_data['decision_2']:
|
elif 'decision_2' in ticket_data and ticket_data['decision_2']:
|
||||||
wp.decision = ticket_data['decision_2']
|
decision = ticket_data['decision_2']
|
||||||
if ticket_data['decision_2'] in ['返工', '返修']:
|
|
||||||
pass
|
|
||||||
elif ticket_data['decision_2'] in ['让步接收']:
|
wp.ng_sign = decision
|
||||||
wp.act_state = WProduct.WPR_ACT_STATE_OK
|
if decision in [WProduct.NG_BACK_WORK, WProduct.NG_BACK_FIX]:
|
||||||
wt.save()
|
step = Step.objects.get(id=ticket_data['back_step'])
|
||||||
wp.save()
|
wp.step = step
|
||||||
|
# 找到当时所属的计划
|
||||||
|
sp = SubProductionPlan.objects.filter(ow_subplan__wproduct=wp,
|
||||||
|
ow_subplan__operation__is_submited=True, ow_subplan__operation__step=step).first()
|
||||||
|
if sp:
|
||||||
|
wp.subproduction_plan = sp
|
||||||
|
wt.save()
|
||||||
|
wp.ticket = None # 解除当前工单
|
||||||
|
wp.act_state = WProduct.WPR_ACT_STATE_DOWAIT
|
||||||
|
wp.save()
|
||||||
|
# 更新子计划合格进度
|
||||||
|
WpmServies.update_subproduction_progress_main(sp=sp)
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise exceptions.APIException('返回步骤点错误')
|
||||||
|
|
||||||
|
elif decision in [WProduct.NG_ACCEPT, WProduct.NG_PERMIT]:
|
||||||
|
wp.act_state = WProduct.WPR_ACT_STATE_OK
|
||||||
|
wp.ng_sign = decision
|
||||||
|
wt.save()
|
||||||
|
wp.ticket = None # 解除当前工单
|
||||||
|
wp.save()
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(post_save, sender=WProduct)
|
||||||
|
def update_wproduct_log(sender, instance, created, **kwargs):
|
||||||
|
"""
|
||||||
|
更新产品变动日志
|
||||||
|
"""
|
||||||
|
# update_fields = kwargs['update_fields']
|
||||||
|
WproductFlow.objects.filter(wproduct=instance, subproduction_plan=instance.subproduction_plan).update(is_lastlog=False)
|
||||||
|
ins = WproductFlow()
|
||||||
|
ins.wproduct = instance
|
||||||
|
for f in WproductFlow._meta.fields:
|
||||||
|
if f.name not in ['id', 'create_time', 'update_time', 'wproduct', 'is_lastlog']:
|
||||||
|
setattr(ins, f.name, getattr(instance, f.name, None))
|
||||||
|
ins.save()
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
from django.db.models.expressions import F
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from rest_framework.generics import CreateAPIView, GenericAPIView
|
from rest_framework.generics import CreateAPIView, GenericAPIView
|
||||||
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
|
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
|
||||||
|
|
@ -179,14 +180,21 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
半成品
|
半成品
|
||||||
"""
|
"""
|
||||||
perms_map={'*':'*'}
|
perms_map={'*':'*'}
|
||||||
queryset = WProduct.objects.select_related('step', 'material', 'subproduction_plan').filter(is_hidden=False)
|
queryset = WProduct.objects.select_related('step', 'material', 'subproduction_plan')
|
||||||
serializer_class = WProductListSerializer
|
serializer_class = WProductListSerializer
|
||||||
filterset_class = WProductFilterSet
|
filterset_class = WProductFilterSet
|
||||||
search_fields = ['number']
|
search_fields = ['number']
|
||||||
ordering_fields = ['id']
|
ordering_fields = ['id']
|
||||||
ordering = ['id']
|
ordering = ['id']
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
queryset = self.queryset
|
||||||
|
if self.request.query_params.get('tag', None) != 'show_hidden':
|
||||||
|
queryset = queryset.filter(is_hidden=False)
|
||||||
|
return queryset
|
||||||
|
|
||||||
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WpmTestFormInitSerializer)
|
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WpmTestFormInitSerializer)
|
||||||
|
@transaction.atomic
|
||||||
def test_init(self, request, pk=None):
|
def test_init(self, request, pk=None):
|
||||||
"""
|
"""
|
||||||
检验记录创建及初始化
|
检验记录创建及初始化
|
||||||
|
|
@ -225,6 +233,8 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
savedict['type'] = TestRecord.TEST_COMB
|
savedict['type'] = TestRecord.TEST_COMB
|
||||||
tr = TestRecord.objects.create(**savedict)
|
tr = TestRecord.objects.create(**savedict)
|
||||||
wproduct.test = tr
|
wproduct.test = tr
|
||||||
|
wproduct.update_by = request.user
|
||||||
|
wproduct.update_time = timezone.now()
|
||||||
wproduct.save()
|
wproduct.save()
|
||||||
# 创建检验条目
|
# 创建检验条目
|
||||||
for i in RecordFormField.objects.filter(form=form, is_deleted=False):
|
for i in RecordFormField.objects.filter(form=form, is_deleted=False):
|
||||||
|
|
@ -282,7 +292,12 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
FIFOItemProduct.objects.bulk_create(ips)
|
FIFOItemProduct.objects.bulk_create(ips)
|
||||||
# 更新库存并修改半成品进行状态
|
# 更新库存并修改半成品进行状态
|
||||||
update_inm(fifo)
|
update_inm(fifo)
|
||||||
wproducts.update(act_state=WProduct.WPR_ACT_STATE_INM, warehouse=warehouse, update_by=request.user, update_time=timezone.now())
|
for i in wproducts:
|
||||||
|
i.act_state = WProduct.WPR_ACT_STATE_INM
|
||||||
|
i.warehouse = warehouse
|
||||||
|
i.update_by = request.user
|
||||||
|
i.update_time = timezone.now()
|
||||||
|
i.save()
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WproductPutInSerializer)
|
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WproductPutInSerializer)
|
||||||
|
|
@ -343,7 +358,8 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
vdata = serializer.validated_data
|
vdata = serializer.validated_data
|
||||||
if obj.act_state == WProduct.WPR_ACT_STATE_NOTOK:
|
if obj.act_state == WProduct.WPR_ACT_STATE_NOTOK:
|
||||||
pass
|
pass
|
||||||
elif obj.step.process.id == 1: # 如果是冷加工可直接报废
|
elif obj.step.process.id == 1 and \
|
||||||
|
obj.act_state in [WProduct.WPR_ACT_STATE_DOWAIT, WProduct.WPR_ACT_STATE_TOTEST]: # 如果是冷加工可直接报废
|
||||||
if vdata.get('scrap_reason', None):
|
if vdata.get('scrap_reason', None):
|
||||||
obj.scrap_reason = vdata['scrap_reason']
|
obj.scrap_reason = vdata['scrap_reason']
|
||||||
else:
|
else:
|
||||||
|
|
@ -352,6 +368,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
raise exceptions.APIException('该产品不可报废')
|
raise exceptions.APIException('该产品不可报废')
|
||||||
obj.act_state = WProduct.WPR_ACT_STATE_SCRAP
|
obj.act_state = WProduct.WPR_ACT_STATE_SCRAP
|
||||||
obj.update_by = request.user
|
obj.update_by = request.user
|
||||||
|
obj.update_time = timezone.now()
|
||||||
obj.save()
|
obj.save()
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
|
@ -369,12 +386,14 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
发起不合格审理单
|
发起不合格审理单
|
||||||
"""
|
"""
|
||||||
obj = self.get_object()
|
obj = self.get_object()
|
||||||
if obj.act_state != WProduct.WPR_ACT_STATE_NOTOK:
|
if obj.act_state != WProduct.WPR_ACT_STATE_NOTOK or obj.ng_sign is not None\
|
||||||
raise exceptions.APIException('非检验不合格产品不可发起不合格审理')
|
or obj.ticket is not None:
|
||||||
|
raise exceptions.APIException('该产品不可发起不合格审理')
|
||||||
workflow = Workflow.objects.filter(name='不合格品审理单', is_deleted=False).first()
|
workflow = Workflow.objects.filter(name='不合格品审理单', is_deleted=False).first()
|
||||||
if workflow:
|
if workflow:
|
||||||
exist_data = {
|
exist_data = {
|
||||||
'wproduct':obj.id,
|
'wproduct':obj.id,
|
||||||
|
'wproduct_number':obj.number,
|
||||||
'wproduct_name':obj.material.name,
|
'wproduct_name':obj.material.name,
|
||||||
'wproduct_specification':obj.material.specification,
|
'wproduct_specification':obj.material.specification,
|
||||||
'finder':request.user.id,
|
'finder':request.user.id,
|
||||||
|
|
@ -537,11 +556,10 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
||||||
else:
|
else:
|
||||||
wp.act_state = WProduct.WPR_ACT_STATE_TOTEST
|
wp.act_state = WProduct.WPR_ACT_STATE_TOTEST
|
||||||
wp.material = wsp.main_product
|
wp.material = wsp.main_product
|
||||||
# 更新子计划进度
|
# 更新子计划生产进度
|
||||||
instance = SubProductionProgress.objects.get(subproduction_plan=wsp,
|
# 如果产品有返工标记不做计算
|
||||||
is_main=True, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
if wp.ng_sign not in [WProduct.NG_BACK_FIX, WProduct.NG_BACK_WORK]:
|
||||||
instance.count_real = instance.count_real + 1 # 这个地方可能会有问题,不够严谨
|
WpmServies.update_subproduction_progress_main(sp=wsp)
|
||||||
instance.save()
|
|
||||||
wp.operation = None
|
wp.operation = None
|
||||||
wp.update_by = request.user
|
wp.update_by = request.user
|
||||||
wp.save()
|
wp.save()
|
||||||
|
|
@ -554,7 +572,8 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
||||||
act_state=WProduct.WPR_ACT_STATE_DOWAIT, remark='',
|
act_state=WProduct.WPR_ACT_STATE_DOWAIT, remark='',
|
||||||
subproduction_plan=i.subproduction_plan)
|
subproduction_plan=i.subproduction_plan)
|
||||||
for x in range(i.count):
|
for x in range(i.count):
|
||||||
WProduct.objects.create(**wpr)
|
WProduct.objects.create(**wpr)
|
||||||
|
WpmServies.update_subproduction_progress_main(sp=i.subproduction_plan)
|
||||||
elif step.type == Step.STEP_TYPE_COMB:
|
elif step.type == Step.STEP_TYPE_COMB:
|
||||||
oms_w = OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT,
|
oms_w = OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT,
|
||||||
subproduction_progress__is_main=True)
|
subproduction_progress__is_main=True)
|
||||||
|
|
@ -571,9 +590,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
||||||
else:
|
else:
|
||||||
wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST
|
wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST
|
||||||
# 更新子计划进度
|
# 更新子计划进度
|
||||||
instance = oms_w.subproduction_progress
|
WpmServies.update_subproduction_progress_main(sp=oms_w.subproduction_plan)
|
||||||
instance.count_real = instance.count_real + 1 # 这个地方可能会有问题,不够严谨
|
|
||||||
instance.save()
|
|
||||||
wproduct.create_by = request.user
|
wproduct.create_by = request.user
|
||||||
wproduct.save()
|
wproduct.save()
|
||||||
# 隐藏原半成品
|
# 隐藏原半成品
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,8 @@ INSTALLED_APPS = [
|
||||||
'apps.qm',
|
'apps.qm',
|
||||||
'apps.pm',
|
'apps.pm',
|
||||||
'apps.wpm',
|
'apps.wpm',
|
||||||
'apps.srm'
|
'apps.srm',
|
||||||
|
'apps.develop'
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ urlpatterns = [
|
||||||
path('api/pm/', include('apps.pm.urls')),
|
path('api/pm/', include('apps.pm.urls')),
|
||||||
path('api/wpm/', include('apps.wpm.urls')),
|
path('api/wpm/', include('apps.wpm.urls')),
|
||||||
path('api/srm/', include('apps.srm.urls')),
|
path('api/srm/', include('apps.srm.urls')),
|
||||||
|
path('api/develop/', include('apps.develop.urls')),
|
||||||
# 工具
|
# 工具
|
||||||
path('api/utils/signature/', GenSignature.as_view()),
|
path('api/utils/signature/', GenSignature.as_view()),
|
||||||
path('api/utils/develop/', UpdateDevelop.as_view()),
|
path('api/utils/develop/', UpdateDevelop.as_view()),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue