Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop
This commit is contained in:
commit
9fd1e20008
|
|
@ -147,7 +147,9 @@ export default {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 50px;
|
line-height: 50px;
|
||||||
border-radius: 26px;
|
border-radius: 26px;
|
||||||
|
background: #ffffff;
|
||||||
border: 2px solid #409EFF;
|
border: 2px solid #409EFF;
|
||||||
|
box-shadow: 0 0 8px 3px rgba(0,0,0,0.1);
|
||||||
}
|
}
|
||||||
.typeWrap{
|
.typeWrap{
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
||||||
|
|
@ -521,6 +521,13 @@ export const asyncRoutes = [
|
||||||
meta: { title: '工单处理', icon: 'example',noCache: true,},
|
meta: { title: '工单处理', icon: 'example',noCache: true,},
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'ticketDetail',
|
||||||
|
name: 'ticketDetail',
|
||||||
|
component: () => import('@/views/workflow/ticketDetail'),
|
||||||
|
meta: { title: '工单详情', icon: 'example',noCache: true,},
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -52,22 +52,24 @@
|
||||||
</div>
|
</div>
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="list"
|
:data="planList"
|
||||||
border fit stripe
|
border fit stripe
|
||||||
height="300"
|
height="300"
|
||||||
>
|
>
|
||||||
<el-table-column type="index" width="50" />
|
<el-table-column type="index" width="50" />
|
||||||
<el-table-column label="任务编号">
|
<el-table-column label="任务编号" prop="number">
|
||||||
<template slot-scope="scope">{{ scope.row.id }}</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">{{ scope.row.product_.name }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="产品型号">
|
<el-table-column label="产品型号">
|
||||||
<template slot-scope="scope">{{ scope.row.card }}</template>
|
<template slot-scope="scope">{{ scope.row.product_.specification }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="生产数量">
|
<el-table-column label="生产数量" prop="count">
|
||||||
<template slot-scope="scope">{{ scope.row.sco }}</template>
|
</el-table-column>
|
||||||
|
<el-table-column label="开始时间" prop="start_date">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="结束时间" prop="end_date">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
@ -102,7 +104,7 @@
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-card>
|
<el-card>
|
||||||
<div class="dashboardCardHand">
|
<div class="dashboardCardHand">
|
||||||
<div class="dashboardCardTitle">库存列表</div>
|
<div class="dashboardCardTitle">库存列表 <span class="stockMore" @click="stockMore">更多>></span></div>
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<el-pagination
|
<el-pagination
|
||||||
:current-page.sync="stockPage"
|
:current-page.sync="stockPage"
|
||||||
|
|
@ -119,30 +121,29 @@
|
||||||
</div>
|
</div>
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="list"
|
:data="stockList"
|
||||||
border fit stripe
|
border fit stripe
|
||||||
height="300"
|
height="300"
|
||||||
>
|
>
|
||||||
<el-table-column label="物料编号">
|
<el-table-column label="物料编号" prop="material_">
|
||||||
<template slot-scope="scope">{{ scope.row.id }}</template>
|
<template slot-scope="scope">{{ scope.row.material_.number }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="物料名称">
|
<el-table-column label="物料名称" prop="material_">
|
||||||
<template slot-scope="scope">{{ scope.row.name }}</template>
|
<template slot-scope="scope">{{ scope.row.material_.name }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="规格型号">
|
<el-table-column label="规格型号" prop="material_">
|
||||||
<template slot-scope="scope">{{ scope.row.card }}</template>
|
<template slot-scope="scope">{{ scope.row.material_.specification }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="物料类型">
|
<el-table-column label="物料类型" prop="material_">
|
||||||
<template slot-scope="scope">{{ scope.row.sco }}</template>
|
<template slot-scope="scope">{{options[scope.row.material_.type]}}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="单位">
|
<el-table-column label="单位" prop="material_">
|
||||||
<template slot-scope="scope">{{ scope.row.name }}</template>
|
<template slot-scope="scope">{{scope.row.material_.unit}}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="库存">
|
<el-table-column label="库存" prop="count">
|
||||||
<template slot-scope="scope">{{ scope.row.card }}</template>
|
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="仓库">
|
<el-table-column label="仓库" prop="warehouse_">
|
||||||
<template slot-scope="scope">{{ scope.row.sco }}</template>
|
<template slot-scope="scope">{{ scope.row.warehouse_.name }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
@ -163,25 +164,25 @@
|
||||||
</el-pagination>
|
</el-pagination>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="lists">
|
<div>
|
||||||
<ul style="padding-right: 40px">
|
<ul class="lists">
|
||||||
<li style="height: 50px;line-height: 50px;font-size: 20px">
|
<li class="listItem">
|
||||||
<div style="display: flex;justify-content: space-between">
|
<div class="itemText">
|
||||||
<span>玻璃低于安全库存</span><span>2021-12-30</span>
|
<span>玻璃低于安全库存</span><span>2021-12-30</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li style="height: 50px;line-height: 50px;font-size: 20px">
|
<li class="listItem">
|
||||||
<div style="display: flex;justify-content: space-between">
|
<div class="itemText">
|
||||||
<span>某某批货临近交货日期</span><span>2021-12-20</span>
|
<span>某某批货临近交货日期</span><span>2021-12-20</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li style="height: 50px;line-height: 50px;font-size: 20px">
|
<li class="listItem">
|
||||||
<div style="display: flex;justify-content: space-between">
|
<div class="itemText">
|
||||||
<span>玻璃低于安全库存</span><span>2021-11-30</span>
|
<span>玻璃低于安全库存</span><span>2021-11-30</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li style="height: 50px;line-height: 50px;font-size: 20px">
|
<li class="listItem">
|
||||||
<div style="display: flex;justify-content: space-between">
|
<div class="itemText">
|
||||||
<span>某某批货临近交货日期</span><span>2021-11-20</span>
|
<span>某某批货临近交货日期</span><span>2021-11-20</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -204,6 +205,9 @@
|
||||||
<script>
|
<script>
|
||||||
import echarts from 'echarts'
|
import echarts from 'echarts'
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
|
import { getInventoryList } from "@/api/inm";
|
||||||
|
import { getProductionplanList} from "@/api/pm";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -212,19 +216,31 @@ export default {
|
||||||
stockPage:1,
|
stockPage:1,
|
||||||
stockPageSize:10,
|
stockPageSize:10,
|
||||||
stockTotal:100,
|
stockTotal:100,
|
||||||
remindPage:2,
|
remindPage:1,
|
||||||
remindPageSize:20,
|
remindPageSize:20,
|
||||||
remindTotal:100,
|
remindTotal:100,
|
||||||
tableIndex:null,
|
tableIndex:null,
|
||||||
chartIndex:null,
|
chartIndex:null,
|
||||||
tableDate:'2021-12',
|
tableDate:'2021-12',
|
||||||
chartDate:'2021-12',
|
chartDate:'2021-12',
|
||||||
|
planList:[],
|
||||||
|
stockList:[],
|
||||||
|
remindList:[],
|
||||||
list:[
|
list:[
|
||||||
{id:1,name:'HIehd9',card:'3337',sco:'REF-32'},
|
{id:1,name:'HIehd9',card:'3337',sco:'REF-32'},
|
||||||
{id:1,name:'HIehd9',card:'3337',sco:'REF-32'},
|
{id:1,name:'HIehd9',card:'3337',sco:'REF-32'},
|
||||||
{id:1,name:'HIehd9',card:'3337',sco:'REF-32'}
|
{id:1,name:'HIehd9',card:'3337',sco:'REF-32'}
|
||||||
],
|
],
|
||||||
|
options:{
|
||||||
|
|
||||||
|
"1":'成品',
|
||||||
|
"2":'半成品',
|
||||||
|
"3":'主要原料',
|
||||||
|
"4":'辅助材料',
|
||||||
|
"5":'加工工具',
|
||||||
|
"6":'辅助工装',
|
||||||
|
|
||||||
|
},
|
||||||
seriesData:[80,60,60, 70, 76, 80, 90, 70],
|
seriesData:[80,60,60, 70, 76, 80, 90, 70],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -244,6 +260,29 @@ export default {
|
||||||
this.$router.push({name:'ticket',params:{}})
|
this.$router.push({name:'ticket',params:{}})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
//任务排期列表
|
||||||
|
getPlanList() {
|
||||||
|
let that = this;
|
||||||
|
this.listLoading = true;
|
||||||
|
getProductionplanList({page:0}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
that.planList = response.data;
|
||||||
|
}
|
||||||
|
this.listLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//库存列表
|
||||||
|
getStockList() {
|
||||||
|
let that = this;
|
||||||
|
this.listLoading = true;
|
||||||
|
getInventoryList({page:this.stockPage,page_size:this.stockPageSize}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
that.stockList = response.data.results;
|
||||||
|
that.stockTotal = response.data.count;
|
||||||
|
}
|
||||||
|
this.listLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
//图标渲染
|
//图标渲染
|
||||||
drawChart() {
|
drawChart() {
|
||||||
this.chartColumn = echarts.init(document.getElementById('chartColumn'));
|
this.chartColumn = echarts.init(document.getElementById('chartColumn'));
|
||||||
|
|
@ -274,7 +313,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
name:'工序',
|
// name:'工序',
|
||||||
axisTick: {
|
axisTick: {
|
||||||
show: false
|
show: false
|
||||||
},
|
},
|
||||||
|
|
@ -328,6 +367,9 @@ export default {
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
stockMore(){
|
||||||
|
this.$router.push({name:'warehouse',params:{}})
|
||||||
|
},
|
||||||
//便捷查询按钮
|
//便捷查询按钮
|
||||||
convenientClick(index,type){
|
convenientClick(index,type){
|
||||||
let startTime = '',endTime = '',url='',activeIndex = '1',obj = new Object();
|
let startTime = '',endTime = '',url='',activeIndex = '1',obj = new Object();
|
||||||
|
|
@ -377,7 +419,15 @@ export default {
|
||||||
this.stockPage = 1;
|
this.stockPage = 1;
|
||||||
},
|
},
|
||||||
handleStockCurrentChange(val){
|
handleStockCurrentChange(val){
|
||||||
console.log(`当前页: ${val}`);
|
let that = this;
|
||||||
|
this.listLoading = true;
|
||||||
|
getInventoryList({page:val,page_size:this.stockPageSize}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
that.stockList = response.data.results;
|
||||||
|
that.stockTotal = response.data.count;
|
||||||
|
}
|
||||||
|
this.listLoading = false;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
handleRemindSizeChange(val){
|
handleRemindSizeChange(val){
|
||||||
this.remindPageSize = val;
|
this.remindPageSize = val;
|
||||||
|
|
@ -389,7 +439,9 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted () {
|
mounted () {
|
||||||
this.drawChart()
|
this.drawChart();
|
||||||
|
this.getPlanList();
|
||||||
|
this.getStockList();
|
||||||
},
|
},
|
||||||
updated () {
|
updated () {
|
||||||
this.drawChart()
|
this.drawChart()
|
||||||
|
|
@ -409,6 +461,7 @@ export default {
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
.cards{
|
.cards{
|
||||||
width: 240px;
|
width: 240px;
|
||||||
|
max-width: 18%;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
background: #abccec;
|
background: #abccec;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
@ -416,7 +469,7 @@ export default {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
float: left;
|
float: left;
|
||||||
margin: 15px;
|
margin: 15px 1%;
|
||||||
.cardFirstText{
|
.cardFirstText{
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
|
|
@ -437,9 +490,15 @@ export default {
|
||||||
.dashboardCardTitle{
|
.dashboardCardTitle{
|
||||||
height: 35px;
|
height: 35px;
|
||||||
line-height:35px;
|
line-height:35px;
|
||||||
font-size: 24px;
|
font-size: 20px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
.stockMore{
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
color: #409EFF;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.dashboardCardFilter{
|
.dashboardCardFilter{
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -472,5 +531,17 @@ export default {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.lists{
|
||||||
|
padding-right: 40px;
|
||||||
|
.listItem{
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
font-size: 18px;
|
||||||
|
.itemText{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@
|
||||||
<el-link v-if="scope.row.state_.type==1&&userId==1" type="danger" @click="handleClose(scope,'2')">关闭</el-link>
|
<el-link v-if="scope.row.state_.type==1&&userId==1" type="danger" @click="handleClose(scope,'2')">关闭</el-link>
|
||||||
<!--如果state_.retreat为可退回,则显示撤回按钮 state_.type==1处于草稿状态 -->
|
<!--如果state_.retreat为可退回,则显示撤回按钮 state_.type==1处于草稿状态 -->
|
||||||
<el-link v-if="scope.row.state_.enable_retreat&&userId==scope.row.create_by&&scope.row.state_.type!==1" type="danger" @click="handleClose(scope,'1')">撤回</el-link>
|
<el-link v-if="scope.row.state_.enable_retreat&&userId==scope.row.create_by&&scope.row.state_.type!==1" type="danger" @click="handleClose(scope,'1')">撤回</el-link>
|
||||||
|
<el-link type="primary" @click="handleDetails(scope)">详情</el-link>
|
||||||
<el-link type="success" @click="handleDelete(scope)">删除</el-link>
|
<el-link type="success" @click="handleDelete(scope)">删除</el-link>
|
||||||
<el-link type="success" @click="handlePicture(scope)">查看流程图</el-link>
|
<el-link type="success" @click="handlePicture(scope)">查看流程图</el-link>
|
||||||
<el-link type="success" @click="handleLogs(scope)">工单日志</el-link>
|
<el-link type="success" @click="handleLogs(scope)">工单日志</el-link>
|
||||||
|
|
@ -117,6 +118,7 @@
|
||||||
<el-link v-else-if="(scope.row.act_state==1||scope.row.act_state==3)&&scope.row.participant_type!==2&&scope.row.state_.type===0" type="primary" @click="handleDetail(scope)">处理</el-link>
|
<el-link v-else-if="(scope.row.act_state==1||scope.row.act_state==3)&&scope.row.participant_type!==2&&scope.row.state_.type===0" type="primary" @click="handleDetail(scope)">处理</el-link>
|
||||||
-->
|
-->
|
||||||
<el-link v-if="scope.row.state_.type==1&&userId==1" type="danger" @click="handleClose(scope,'2')">关闭</el-link>
|
<el-link v-if="scope.row.state_.type==1&&userId==1" type="danger" @click="handleClose(scope,'2')">关闭</el-link>
|
||||||
|
<el-link type="primary" @click="handleDetails(scope)">详情</el-link>
|
||||||
<el-link type="success" @click="handlePicture(scope)">查看流程图</el-link>
|
<el-link type="success" @click="handlePicture(scope)">查看流程图</el-link>
|
||||||
<el-link type="success" @click="handleLogs(scope)">工单日志</el-link>
|
<el-link type="success" @click="handleLogs(scope)">工单日志</el-link>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -163,6 +165,7 @@
|
||||||
<template slot-scope="scope" v-if="scope.row.state_">
|
<template slot-scope="scope" v-if="scope.row.state_">
|
||||||
<el-link v-if="scope.row.state_.enable_retreat&&scope.row.state_.type!==1" type="danger" @click="handleClose(scope,'1')">撤回</el-link>
|
<el-link v-if="scope.row.state_.enable_retreat&&scope.row.state_.type!==1" type="danger" @click="handleClose(scope,'1')">撤回</el-link>
|
||||||
<el-link v-if="scope.row.state_.type==1" type="danger" @click="handleClose(scope,'2')">关闭</el-link>
|
<el-link v-if="scope.row.state_.type==1" type="danger" @click="handleClose(scope,'2')">关闭</el-link>
|
||||||
|
<el-link type="primary" @click="handleDetails(scope)">详情</el-link>
|
||||||
<el-link type="success" @click="handleDelete(scope)">删除</el-link>
|
<el-link type="success" @click="handleDelete(scope)">删除</el-link>
|
||||||
<el-link type="success" @click="handlePicture(scope)">查看流程图</el-link>
|
<el-link type="success" @click="handlePicture(scope)">查看流程图</el-link>
|
||||||
<el-link type="success" @click="handleLogs(scope)">工单日志</el-link>
|
<el-link type="success" @click="handleLogs(scope)">工单日志</el-link>
|
||||||
|
|
@ -208,6 +211,7 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" label="操作">
|
<el-table-column align="center" label="操作">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
|
<el-link type="primary" @click="handleDetails(scope)">详情</el-link>
|
||||||
<el-link type="danger" @click="handlePicture(scope)">查看流程图</el-link>
|
<el-link type="danger" @click="handlePicture(scope)">查看流程图</el-link>
|
||||||
<el-link type="success" @click="handleLogs(scope)">工单日志</el-link>
|
<el-link type="success" @click="handleLogs(scope)">工单日志</el-link>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -866,6 +870,10 @@
|
||||||
handleDetail(scope){
|
handleDetail(scope){
|
||||||
this.$router.push({name:"ticketHandle",params:{ticketId:scope.row.id,workflow:scope.row.workflow}})
|
this.$router.push({name:"ticketHandle",params:{ticketId:scope.row.id,workflow:scope.row.workflow}})
|
||||||
},
|
},
|
||||||
|
//工单详情
|
||||||
|
handleDetails(scope){
|
||||||
|
this.$router.push({name:"ticketDetail",params:{ticketId:scope.row.id,workflow:scope.row.workflow}})
|
||||||
|
},
|
||||||
//接单
|
//接单
|
||||||
handleGetTicket(scope){
|
handleGetTicket(scope){
|
||||||
let ticketId = scope.row.id;
|
let ticketId = scope.row.id;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,563 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-card style="margin-bottom: 10px">
|
||||||
|
<el-steps :active="actives" spac="400px" align-center="" style="padding-top: 20px;">
|
||||||
|
<el-step :title="item.name" v-for="item in flowSteps " :key="item.id"></el-step>
|
||||||
|
</el-steps>
|
||||||
|
</el-card>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-card>
|
||||||
|
<svg height=800 id="mySvg" style="width:100%!important;"></svg>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="16">
|
||||||
|
<el-card style="margin-left: 10px">
|
||||||
|
<p style="text-align: center;font-size: 20px">{{ticketDetail.title}}</p>
|
||||||
|
<el-col :span="12">
|
||||||
|
<div class="items">
|
||||||
|
<span class="itemLabel">工作流:</span>
|
||||||
|
<span>{{ticketDetail.workflow_.name}}</span>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<div class="items">
|
||||||
|
<span class="itemLabel">流水号:</span>
|
||||||
|
<span>{{ticketDetail.sn}}</span>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<div class="items">
|
||||||
|
<span class="itemLabel">创建时间:</span>
|
||||||
|
<span>{{ticketDetail.create_time}}</span>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col v-for="item in ticketDetail.ticket_data_" :key="item.id" :span="12">
|
||||||
|
<div class="items">
|
||||||
|
<span class="itemLabel">{{item.field_name}}:</span>
|
||||||
|
<span>{{item.field_display}}</span>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-card>
|
||||||
|
<el-card style="margin-left: 10px">
|
||||||
|
<el-table :data="logs" fit stripe
|
||||||
|
style="width: 100%;border-top:1px solid #EBEEF5;"
|
||||||
|
height="500"
|
||||||
|
highlight-current-row
|
||||||
|
>
|
||||||
|
<el-table-column label="工单标题" min-width="100">
|
||||||
|
<template slot-scope="scope" v-if="scope.row.ticket_data">
|
||||||
|
<span>{{scope.row.ticket_data.title}}中</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="进行状态" min-width="100">
|
||||||
|
<template slot-scope="scope" v-if="scope.row.state_">
|
||||||
|
<span v-if="scope.row.state_.type==0">{{scope.row.state_.name}}中</span>
|
||||||
|
<span v-else>已{{scope.row.state_.name}}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作人" min-width="100">
|
||||||
|
<template slot-scope="scope" v-if="scope.row.participant_">{{ scope.row.participant_.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作意见" min-width="100" prop="suggestion">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="更新时间" min-width="100" prop="update_time">
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script src="https://d3js.org/d3.v4.min.js"></script>
|
||||||
|
<script>
|
||||||
|
import {getOrgAll} from "@/api/org";
|
||||||
|
import {upUrl, upHeaders} from "@/api/file";
|
||||||
|
import {getUserList} from "@/api/user";
|
||||||
|
import {
|
||||||
|
getWorkflowList, getWfCustomfieldList, getWfStateList, getWfTransitionList, ticketHandle
|
||||||
|
, getWfFlowSteps, getTicketDetail, getTicketTransitions, getTicketFlowlog, ticketRetreat,
|
||||||
|
ticketAddNode, ticketAddNodeEnd, ticketClose
|
||||||
|
} from "@/api/workflow";
|
||||||
|
import Pagination from "@/components/Pagination";
|
||||||
|
import dagreD3 from 'dagre-d3'
|
||||||
|
import * as d3 from 'd3'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ticketDetail",
|
||||||
|
components: {Pagination},
|
||||||
|
inject: ['reload'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
step: 4,
|
||||||
|
actives: 4,
|
||||||
|
ticketId: 0,
|
||||||
|
stateSteps: 0,
|
||||||
|
ticketForm: {
|
||||||
|
transition: '',
|
||||||
|
ticket_data: {},
|
||||||
|
suggestion: '',
|
||||||
|
},
|
||||||
|
handleType: '1',
|
||||||
|
handleLabel: '撤回原因',
|
||||||
|
handleTitle: '工单撤回',
|
||||||
|
handleForm: {
|
||||||
|
suggestion: '',
|
||||||
|
},
|
||||||
|
addForm: {
|
||||||
|
toadd_user: '',
|
||||||
|
suggestion: '',
|
||||||
|
},
|
||||||
|
tooltip: null,
|
||||||
|
handleRule: {},
|
||||||
|
upUrl: upUrl(),
|
||||||
|
upHeaders: upHeaders(),
|
||||||
|
userId: '',
|
||||||
|
workflow: '',
|
||||||
|
watchedName: '',
|
||||||
|
watchedCreateTime: '',
|
||||||
|
logs: [],
|
||||||
|
orgList: [],
|
||||||
|
staffs: [],
|
||||||
|
edges: [],
|
||||||
|
nodes: [],
|
||||||
|
tooltip: [],
|
||||||
|
fileList: [],
|
||||||
|
workflows: [],
|
||||||
|
flowSteps: [],
|
||||||
|
ticketDetail: {},
|
||||||
|
operationBtn: [],
|
||||||
|
customfields: [],
|
||||||
|
transitions: [],
|
||||||
|
limitedAdd: false,
|
||||||
|
limitedHandle: false,
|
||||||
|
ticketFormRule: {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
let that = this;
|
||||||
|
that.userId = sessionStorage.getItem('userId')
|
||||||
|
let ticketId = that.ticketId = this.$route.params.ticketId;
|
||||||
|
let workflow = that.workflow = this.$route.params.workflow;
|
||||||
|
let handleTicketId = sessionStorage.getItem('handleTicketId');
|
||||||
|
let handleTicketWorkflow = sessionStorage.getItem('handleTicketWorkflow');
|
||||||
|
if (ticketId && workflow) {
|
||||||
|
if (handleTicketId && handleTicketWorkflow) {
|
||||||
|
sessionStorage.removeItem('handleTicketId');
|
||||||
|
sessionStorage.removeItem('handleTicketWorkflow');
|
||||||
|
sessionStorage.setItem('handleTicketId', ticketId);
|
||||||
|
sessionStorage.setItem('handleTicketWorkflow', workflow);
|
||||||
|
} else {
|
||||||
|
sessionStorage.setItem('handleTicketId', ticketId);
|
||||||
|
sessionStorage.setItem('handleTicketWorkflow', workflow);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ticketId = that.ticketId = handleTicketId;
|
||||||
|
workflow = that.workflow = handleTicketWorkflow;
|
||||||
|
}
|
||||||
|
this.getTicketFlowlogs(ticketId);
|
||||||
|
getTicketTransitions(ticketId).then(res => {
|
||||||
|
this.operationBtn = res.data;
|
||||||
|
})
|
||||||
|
getOrgAll().then((orgRes) => {
|
||||||
|
that.orgList = orgRes.data;
|
||||||
|
getUserList({page: 0}).then(userRes => {
|
||||||
|
if (userRes.data) {
|
||||||
|
that.staffs = userRes.data;
|
||||||
|
getWfFlowSteps(ticketId).then((res) => {
|
||||||
|
if (res.data) {
|
||||||
|
//流程步骤数组
|
||||||
|
that.flowSteps = res.data;
|
||||||
|
getTicketDetail(ticketId).then((res) => {
|
||||||
|
if (res.data) {
|
||||||
|
that.tooltip = that.createTooltip();
|
||||||
|
that.ticketDetail = res.data;
|
||||||
|
for (let i = 0; i < that.ticketDetail.ticket_data_.length; i++) {
|
||||||
|
if (that.ticketDetail.ticket_data_[i].label === "sys_user") {
|
||||||
|
that.ticketDetail.ticket_data_[i].field_choice = that.staffs;
|
||||||
|
}
|
||||||
|
if (that.ticketDetail.ticket_data_[i].label === "deptSelect") {
|
||||||
|
that.ticketDetail.ticket_data_[i].field_choice = that.orgList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(that.ticketDetail.state_.enable_retreat);
|
||||||
|
let state = res.data.state;
|
||||||
|
let dat = that.flowSteps.filter((item) => {
|
||||||
|
return item.id == state;
|
||||||
|
})
|
||||||
|
debugger;
|
||||||
|
let state_fields = dat[0].state_fields;
|
||||||
|
if (state_fields !== {}) {
|
||||||
|
for (let labe in state_fields) {
|
||||||
|
for (let j = 0; j < that.ticketDetail.ticket_data_.length; j++) {
|
||||||
|
if (that.ticketDetail.ticket_data_[j].field_key === labe) {
|
||||||
|
debugger;
|
||||||
|
console.log(labe)
|
||||||
|
console.log(state_fields[labe])
|
||||||
|
if (state_fields[labe] !== 4) {
|
||||||
|
that.ticketDetail.ticket_data_[j].is_hidden = false
|
||||||
|
} else {
|
||||||
|
that.ticketDetail.ticket_data_[j].is_hidden = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
that.sort = dat[0].sort;
|
||||||
|
that.actives = that.flowSteps.indexOf(dat[0]);
|
||||||
|
if (that.flowSteps.length - that.actives > 1) {
|
||||||
|
} else {
|
||||||
|
that.actives = that.flowSteps.length;
|
||||||
|
}
|
||||||
|
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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
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() {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getUser() {
|
||||||
|
getUserList({}).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
this.staffs = res.data.results;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
//工单流转记录
|
||||||
|
getTicketFlowlogs(id) {
|
||||||
|
getTicketFlowlog(id).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
this.logs = res.data;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handlePreview(file) {
|
||||||
|
if ("url" in file) {
|
||||||
|
window.open(file.url);
|
||||||
|
} else {
|
||||||
|
window.open(file.response.data.path);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleUpSuccess(res, file, filelist) {
|
||||||
|
this.process.instruction = res.data.id;
|
||||||
|
},
|
||||||
|
handleRemove(file, filelist) {
|
||||||
|
this.process.instruction = null;
|
||||||
|
},
|
||||||
|
// 创建提示框
|
||||||
|
createTooltip() {
|
||||||
|
return d3
|
||||||
|
.select('body')
|
||||||
|
.append('div')
|
||||||
|
.classed('tooltip', true)
|
||||||
|
.style('opacity', 0)
|
||||||
|
.style('display', 'none')
|
||||||
|
},
|
||||||
|
// tooltip显示
|
||||||
|
tipVisible(textContent) {
|
||||||
|
this.tooltip
|
||||||
|
.transition()
|
||||||
|
.duration(400)
|
||||||
|
.style('opacity', 1)
|
||||||
|
.style('display', 'block')
|
||||||
|
.style('color', '#ffffff')
|
||||||
|
.style('z-index', '3999')
|
||||||
|
.style('padding', '20px 30px')
|
||||||
|
.style('border-radius', '5px')
|
||||||
|
.style('position', 'fixed')
|
||||||
|
.style('background', 'rgba(0,0,0,.7)')
|
||||||
|
this.tooltip
|
||||||
|
.html(textContent)
|
||||||
|
.style('left', `${d3.event.pageX + 15}px`)
|
||||||
|
.style('top', `${d3.event.pageY - 10}px`)
|
||||||
|
},
|
||||||
|
// tooltip隐藏
|
||||||
|
tipHidden() {
|
||||||
|
this.tooltip
|
||||||
|
.transition()
|
||||||
|
.duration(400)
|
||||||
|
.style('opacity', 0)
|
||||||
|
.style('display', 'none')
|
||||||
|
},
|
||||||
|
operationSubmit(id) {
|
||||||
|
this.ticketForm.transition = id;
|
||||||
|
this.ticketForm.ticket_data = this.ticketDetail.ticket_data;
|
||||||
|
let obj = new Object();
|
||||||
|
obj.transition = id;
|
||||||
|
obj.ticket_data = this.ticketDetail.ticket_data;
|
||||||
|
obj.suggestion = this.ticketForm.suggestion;
|
||||||
|
console.log(this.ticketForm);
|
||||||
|
ticketHandle(this.ticketId, obj).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
this.$store.dispatch("user/getCount", {})
|
||||||
|
this.$router.replace({name: "ticket"})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
retreatCancel() {
|
||||||
|
this.limitedHandle = false;
|
||||||
|
},
|
||||||
|
handleSubmit() {
|
||||||
|
let text = '', url = '';
|
||||||
|
if (this.handleType === '1') {
|
||||||
|
text = "确认撤回工单吗?";
|
||||||
|
url = ticketRetreat;
|
||||||
|
} else if (this.handleType === '2') {
|
||||||
|
text = "确认关闭工单吗?";
|
||||||
|
url = ticketClose;
|
||||||
|
}
|
||||||
|
if (this.handleType === '3') {
|
||||||
|
text = "确认处理工单吗?";
|
||||||
|
url = ticketAddNodeEnd;
|
||||||
|
}
|
||||||
|
this.$confirm(text, "温馨提示", {
|
||||||
|
confirmButtonText: "确认",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "warning",
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
url(this.ticketId, this.handleForm).then(res => {
|
||||||
|
this.limitedHandle = false;
|
||||||
|
this.$store.dispatch("user/getCount", {})
|
||||||
|
this.$router.replace({name: "ticket"})
|
||||||
|
this.$message.success("成功");
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleClick(index) {
|
||||||
|
this.limitedHandle = true;
|
||||||
|
this.handleType = index;
|
||||||
|
if (index === '1') {
|
||||||
|
this.handleTitle = '工单撤回';
|
||||||
|
this.handleLabel = '撤回原因';
|
||||||
|
} else if (index === '2') {
|
||||||
|
this.handleTitle = '工单关闭';
|
||||||
|
this.handleLabel = '关闭原因';
|
||||||
|
} else if (index === '3') {
|
||||||
|
this.handleTitle = '加签处理';
|
||||||
|
this.handleLabel = '加签意见';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleAdd() {
|
||||||
|
this.getUser();
|
||||||
|
this.limitedAdd = true;
|
||||||
|
},
|
||||||
|
addCancel() {
|
||||||
|
this.limitedAdd = false;
|
||||||
|
},
|
||||||
|
addSubmit() {
|
||||||
|
ticketAddNode(this.ticketId, this.addForm).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
this.limitedAdd = false;
|
||||||
|
this.$nextTick(function () {
|
||||||
|
this.limitedAdd = true;
|
||||||
|
this.$store.dispatch("user/getCount", {})
|
||||||
|
this.$router.replace({name: "ticket"})
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.svgWrapper {
|
||||||
|
background: #fff;
|
||||||
|
width: 800px;
|
||||||
|
margin: 10vh auto 0;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svgItem {
|
||||||
|
padding: 20px 40px 0;
|
||||||
|
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
|
||||||
|
font-size: 18px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node rect {
|
||||||
|
stroke: #606266;
|
||||||
|
fill: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edgePath path {
|
||||||
|
stroke: #606266;
|
||||||
|
fill: #333;
|
||||||
|
stroke-width: 1.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-icon-close {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.listItem {
|
||||||
|
margin-top: 15px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.listItem > span {
|
||||||
|
width: 100px;
|
||||||
|
text-align: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items {
|
||||||
|
height: 35px;
|
||||||
|
line-height: 35px;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemLabel {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #606266;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -36,10 +36,159 @@
|
||||||
</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" v-show="!item.is_hidden">
|
<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 v-if="item.field_state=='1'" :label="item.field_name">
|
||||||
<span>{{ticketDetail.ticket_data[item.field_key]}}</span>
|
<template v-if="item.field_type=='string'">
|
||||||
|
<el-input v-model="ticketDetail.ticket_data[item.field_key]" :placeholder="item.description" disabled="true"/>
|
||||||
|
</template>
|
||||||
|
<template v-if="item.field_type==='int'">
|
||||||
|
<el-input v-model="ticketDetail.ticket_data[item.field_key]" type="number" :placeholder="item.description" oninput="value=value.replace(/[^\d]/g,'')" disabled="true"/>
|
||||||
|
</template>
|
||||||
|
<template v-if="item.field_type==='float'">
|
||||||
|
<el-input v-model="ticketDetail.ticket_data[item.field_key]" type="number" :placeholder="item.description" disabled="true"/>
|
||||||
|
</template>
|
||||||
|
<template v-if="item.field_type==='date'">
|
||||||
|
<el-date-picker
|
||||||
|
disabled="true"
|
||||||
|
v-model="ticketDetail.ticket_data[item.field_key]"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择日期"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
</el-date-picker>
|
||||||
|
</template>
|
||||||
|
<template v-if="item.field_type==='datetime'">
|
||||||
|
<el-date-picker
|
||||||
|
disabled="true"
|
||||||
|
v-model="ticketDetail.ticket_data[item.field_key]"
|
||||||
|
type="datetime"
|
||||||
|
placeholder="选择日期"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
</el-date-picker>
|
||||||
|
</template>
|
||||||
|
<template v-if="item.field_type==='select'">
|
||||||
|
<el-select style="width: 100%" v-model="ticketDetail.ticket_data[item.field_key]" placeholder="请选择" disabled="true">
|
||||||
|
<el-option
|
||||||
|
v-for="item1 in item.field_choice"
|
||||||
|
:key="item1.id"
|
||||||
|
:label="item1.name"
|
||||||
|
:value="item1.id"
|
||||||
|
>
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
<template v-if="item.field_type==='selects'">
|
||||||
|
<el-select style="width: 100%" multiple v-model="ticketDetail.ticket_data[item.field_key]" placeholder="请选择" disabled="true">
|
||||||
|
<el-option
|
||||||
|
v-for="item1 in item.field_choice"
|
||||||
|
:key="item1.id"
|
||||||
|
:label="item1.name"
|
||||||
|
:value="item1.id"
|
||||||
|
>
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
<template v-if="item.field_type==='textarea'">
|
||||||
|
<el-input type="textarea" :rows="3" v-model="ticketDetail.ticket_data[item.field_key]" placeholder="内容" disabled="true"/>
|
||||||
|
</template>
|
||||||
|
<template v-if="item.field_type==='file'">
|
||||||
|
<el-upload
|
||||||
|
ref="upload"
|
||||||
|
:action="upUrl"
|
||||||
|
:on-preview="handlePreview"
|
||||||
|
:on-success="handleUpSuccess"
|
||||||
|
: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-item>
|
||||||
<el-form-item :label="item.field_name" v-else>
|
<el-form-item
|
||||||
|
v-if="item.field_state=='2'"
|
||||||
|
:label="item.field_name"
|
||||||
|
prop=""
|
||||||
|
:rules="{
|
||||||
|
required: true, message: '不能为空', trigger: 'blur'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template v-if="item.field_type=='string'">
|
||||||
|
<el-input v-model="ticketDetail.ticket_data[item.field_key]" :placeholder="item.description"/>
|
||||||
|
</template>
|
||||||
|
<template v-if="item.field_type==='int'">
|
||||||
|
<el-input v-model="ticketDetail.ticket_data[item.field_key]" type="number" :placeholder="item.description" oninput="value=value.replace(/[^\d]/g,'')" />
|
||||||
|
</template>
|
||||||
|
<template v-if="item.field_type==='float'">
|
||||||
|
<el-input v-model="ticketDetail.ticket_data[item.field_key]" type="number" :placeholder="item.description" />
|
||||||
|
</template>
|
||||||
|
<template v-if="item.field_type==='date'">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="ticketDetail.ticket_data[item.field_key]"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择日期"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
</el-date-picker>
|
||||||
|
</template>
|
||||||
|
<template v-if="item.field_type==='datetime'">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="ticketDetail.ticket_data[item.field_key]"
|
||||||
|
type="datetime"
|
||||||
|
placeholder="选择日期"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
</el-date-picker>
|
||||||
|
</template>
|
||||||
|
<template v-if="item.field_type==='select'">
|
||||||
|
<el-select style="width: 100%" v-model="ticketDetail.ticket_data[item.field_key]" placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="item1 in item.field_choice"
|
||||||
|
:key="item1.id"
|
||||||
|
:label="item1.name"
|
||||||
|
:value="item1.id"
|
||||||
|
>
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
<template v-if="item.field_type==='selects'">
|
||||||
|
<el-select style="width: 100%" multiple v-model="ticketDetail.ticket_data[item.field_key]" placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="item1 in item.field_choice"
|
||||||
|
:key="item1.id"
|
||||||
|
:label="item1.name"
|
||||||
|
:value="item1.id"
|
||||||
|
>
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
<template v-if="item.field_type==='textarea'">
|
||||||
|
<el-input type="textarea" :rows="3" v-model="ticketDetail.ticket_data[item.field_key]" placeholder="内容" />
|
||||||
|
</template>
|
||||||
|
<template v-if="item.field_type==='file'">
|
||||||
|
<el-upload
|
||||||
|
ref="upload"
|
||||||
|
:action="upUrl"
|
||||||
|
:on-preview="handlePreview"
|
||||||
|
:on-success="handleUpSuccess"
|
||||||
|
: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-item
|
||||||
|
v-if="item.field_state=='3'"
|
||||||
|
:label="item.field_name"
|
||||||
|
>
|
||||||
<template v-if="item.field_type=='string'">
|
<template v-if="item.field_type=='string'">
|
||||||
<el-input v-model="ticketDetail.ticket_data[item.field_key]" :placeholder="item.description"/>
|
<el-input v-model="ticketDetail.ticket_data[item.field_key]" :placeholder="item.description"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,11 @@
|
||||||
stripe
|
stripe
|
||||||
highlight-current-row
|
highlight-current-row
|
||||||
max-height="700"
|
max-height="700"
|
||||||
|
|
||||||
>
|
>
|
||||||
<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.material_.name }}</template>
|
<template slot-scope="scope">{{ scope.row.material_.name }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column label="半成品编号">
|
<el-table-column label="半成品编号">
|
||||||
<template slot-scope="scope">{{ scope.row.number }}</template>
|
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -26,12 +24,9 @@
|
||||||
{{ actstate_[scope.row.act_state] }}
|
{{ actstate_[scope.row.act_state] }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
|
|
||||||
<el-table-column label="所在子工序">
|
<el-table-column label="所在子工序">
|
||||||
<template slot-scope="scope">{{ scope.row.step_.name }}</template>
|
<template slot-scope="scope">{{ scope.row.step_.name }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column align="center" label="操作" width="220px">
|
<el-table-column align="center" label="操作" width="220px">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-link
|
<el-link
|
||||||
|
|
@ -46,6 +41,7 @@
|
||||||
</el-link>
|
</el-link>
|
||||||
<el-link
|
<el-link
|
||||||
v-if="checkPermission(['warehouse_update'])"
|
v-if="checkPermission(['warehouse_update'])"
|
||||||
|
type="danger"
|
||||||
@click="handleScrapbcp(scope)"
|
@click="handleScrapbcp(scope)"
|
||||||
>报废
|
>报废
|
||||||
</el-link>
|
</el-link>
|
||||||
|
|
@ -77,8 +73,6 @@
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button @click="dialogFormVisiblebcp = false">取 消</el-button>
|
<el-button @click="dialogFormVisiblebcp = false">取 消</el-button>
|
||||||
|
|
@ -126,13 +120,6 @@
|
||||||
@click="checkRecord(scope,'2')"
|
@click="checkRecord(scope,'2')"
|
||||||
>检验记录
|
>检验记录
|
||||||
</el-link>
|
</el-link>
|
||||||
|
|
||||||
<!--<el-link
|
|
||||||
v-if="checkPermission(['warehouse_update'])"
|
|
||||||
@click="handleInspection(scope,'2')"
|
|
||||||
>
|
|
||||||
检验
|
|
||||||
</el-link>-->
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
@ -209,17 +196,14 @@
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="不合格半成品">
|
<el-tab-pane label="不合格半成品">
|
||||||
<el-card style="margin-top: 2px">
|
<el-card style="margin-top: 2px">
|
||||||
|
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="wproductList4.results"
|
:data="wproductList4.results"
|
||||||
|
|
||||||
border
|
border
|
||||||
fit
|
fit
|
||||||
stripe
|
stripe
|
||||||
highlight-current-row
|
highlight-current-row
|
||||||
max-height="600"
|
max-height="600"
|
||||||
|
|
||||||
>
|
>
|
||||||
<el-table-column type="index" width="50"/>
|
<el-table-column type="index" width="50"/>
|
||||||
<el-table-column label="半成品名称">
|
<el-table-column label="半成品名称">
|
||||||
|
|
@ -234,7 +218,6 @@
|
||||||
{{ actstate_[scope.row.act_state] }}
|
{{ actstate_[scope.row.act_state] }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column label="所在子工序">
|
<el-table-column label="所在子工序">
|
||||||
<template slot-scope="scope">{{ scope.row.step_.name }}</template>
|
<template slot-scope="scope">{{ scope.row.step_.name }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -246,15 +229,18 @@
|
||||||
<el-table-column align="center" label="操作" width="220px">
|
<el-table-column align="center" label="操作" width="220px">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-link
|
<el-link
|
||||||
type="danger"
|
|
||||||
v-if="checkPermission(['warehouse_update'])"
|
v-if="checkPermission(['warehouse_update'])"
|
||||||
|
type="danger"
|
||||||
@click="handleScrap(scope)"
|
@click="handleScrap(scope)"
|
||||||
>报废
|
>
|
||||||
|
报废
|
||||||
</el-link>
|
</el-link>
|
||||||
<el-link type="primary"
|
<el-link
|
||||||
v-if="!scope.row.ticket"
|
v-if="!scope.row.ticket"
|
||||||
|
type="primary"
|
||||||
@click="handleRetrial(scope)"
|
@click="handleRetrial(scope)"
|
||||||
>重审
|
>
|
||||||
|
审理
|
||||||
</el-link>
|
</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -523,7 +509,8 @@
|
||||||
<el-input v-model="item.default_value" :placeholder="item.description"/>
|
<el-input v-model="item.default_value" :placeholder="item.description"/>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="item.field_type==='int'">
|
<template v-if="item.field_type==='int'">
|
||||||
<el-input v-model="item.default_value" type="number" :placeholder="item.description" oninput="value=value.replace(/[^\d]/g,'')" />
|
<el-input v-model="item.default_value" type="number" :placeholder="item.description"
|
||||||
|
oninput="value=value.replace(/[^\d]/g,'')"/>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="item.field_type==='float'">
|
<template v-if="item.field_type==='float'">
|
||||||
<el-input v-model="item.default_value" type="number" :placeholder="item.description"/>
|
<el-input v-model="item.default_value" type="number" :placeholder="item.description"/>
|
||||||
|
|
@ -604,11 +591,11 @@
|
||||||
import checkPermission from "@/utils/permission";
|
import checkPermission from "@/utils/permission";
|
||||||
import customForm from '@/components/customForm/index';
|
import customForm from '@/components/customForm/index';
|
||||||
import reviewForm from '@/components/customForm/review';
|
import reviewForm from '@/components/customForm/review';
|
||||||
import {getWfCustomfieldList,createTicket ,getWorkflowInit} from "@/api/workflow";
|
import { createTicket, getWorkflowInit} from "@/api/workflow";
|
||||||
import {getMaterialList, getrecordformList, getrffieldList} from "@/api/mtm";
|
import { getrecordformList, getrffieldList} from "@/api/mtm";
|
||||||
import {getwproductList, wproductTest, wproductPutin, createputins,testInit,scrap,getRetrial} from "@/api/wpm";
|
import {getwproductList, wproductPutin, createputins, testInit, scrap, getRetrial} from "@/api/wpm";
|
||||||
import {getTestRecord, getTestRecordItem, putTestRecordItem, delTestRecordItem, subTestRecordItem} from "@/api/qm";
|
import {getTestRecord, getTestRecordItem, putTestRecordItem, delTestRecordItem, subTestRecordItem} 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
|
||||||
const defaultetestitem = {};
|
const defaultetestitem = {};
|
||||||
export default {
|
export default {
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,10 @@ from django.db.models import base
|
||||||
from rest_framework import urlpatterns
|
from rest_framework import urlpatterns
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
from apps.develop.views import CleanDataView
|
from apps.develop.views import CleanDataView, UpdateCuttingView
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('cleandata/', CleanDataView.as_view()),
|
path('cleandata/', CleanDataView.as_view()),
|
||||||
|
path('update_cutting/', UpdateCuttingView.as_view())
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
|
from django.db import transaction
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
from rest_framework.decorators import permission_classes
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from rest_framework.permissions import IsAdminUser
|
from rest_framework.permissions import IsAdminUser
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
@ -7,7 +9,8 @@ from apps.mtm.models import Material
|
||||||
from apps.pm.models import ProductionPlan
|
from apps.pm.models import ProductionPlan
|
||||||
from apps.sam.models import Order
|
from apps.sam.models import Order
|
||||||
from apps.wf.models import Ticket
|
from apps.wf.models import Ticket
|
||||||
from apps.wpm.models import Operation
|
from apps.wpm.models import Operation, OperationMaterial, WProduct, WproductFlow
|
||||||
|
from apps.wpm.services import WpmServies
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
class CleanDataView(APIView):
|
class CleanDataView(APIView):
|
||||||
|
|
@ -26,3 +29,21 @@ class CleanDataView(APIView):
|
||||||
Ticket.objects.all().delete(soft=False)
|
Ticket.objects.all().delete(soft=False)
|
||||||
Operation.objects.all().delete()
|
Operation.objects.all().delete()
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateCuttingView(APIView):
|
||||||
|
permission_classes = [IsAdminUser]
|
||||||
|
@transaction.atomic
|
||||||
|
def post(self, request, format=None):
|
||||||
|
"""
|
||||||
|
更新下料清单
|
||||||
|
"""
|
||||||
|
for i in WProduct.objects.all():
|
||||||
|
sp = WproductFlow.objects.filter(wproduct=i).order_by('id').first().subproduction_plan
|
||||||
|
op_q = OperationMaterial.objects.filter(subproduction_plan=sp, operation__step__id=1, operation__is_submited=True)
|
||||||
|
op = op_q.first().operation
|
||||||
|
i.coperation = op
|
||||||
|
i.save()
|
||||||
|
WproductFlow.objects.filter(wproduct=i).update(coperation=op)
|
||||||
|
WpmServies.update_cutting_list_with_operation(op)
|
||||||
|
return Response()
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ from django_filters import rest_framework as filters
|
||||||
from apps.mtm.models import Material, Step
|
from apps.mtm.models import Material, Step
|
||||||
|
|
||||||
from apps.wpm.services import WpmServies
|
from apps.wpm.services import WpmServies
|
||||||
from .models import Operation, WMaterial, WProduct
|
from .models import Operation, OperationMaterial, WMaterial, WProduct
|
||||||
|
|
||||||
class WMaterialFilterSet(filters.FilterSet):
|
class WMaterialFilterSet(filters.FilterSet):
|
||||||
|
|
||||||
|
|
@ -34,3 +34,9 @@ class WProductFilterSet(filters.FilterSet):
|
||||||
if value == 'no_scrap':
|
if value == 'no_scrap':
|
||||||
queryset = queryset.exclude(act_state=WProduct.WPR_ACT_STATE_SCRAP)
|
queryset = queryset.exclude(act_state=WProduct.WPR_ACT_STATE_SCRAP)
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
class CuttingFilterSet(filters.FilterSet):
|
||||||
|
production_plan = filters.NumberFilter(field_name='subproduction_plan__production_plan')
|
||||||
|
class Meta:
|
||||||
|
model = OperationMaterial
|
||||||
|
fields = ['operation', 'subproduction_plan', 'material']
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
# Generated by Django 3.2.9 on 2022-01-04 08:41
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('mtm', '0042_alter_recordformfield_field_type'),
|
||||||
|
('wpm', '0043_auto_20211231_1130'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='operation',
|
||||||
|
name='use_scrap',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='operationmaterial',
|
||||||
|
name='from_batch',
|
||||||
|
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='源批次'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='operationmaterial',
|
||||||
|
name='from_material',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='om_fmaterial', to='mtm.material', verbose_name='源物料'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='operationmaterial',
|
||||||
|
name='use_scrap',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='是否使用的边角料'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='operationwproduct',
|
||||||
|
name='ng_sign',
|
||||||
|
field=models.PositiveSmallIntegerField(blank=True, choices=[(10, '返工'), (20, '返修'), (30, '报废'), (40, '让步接收'), (50, '偏离许可'), (60, '降级使用'), (70, '退回供方'), (80, '召回')], null=True, verbose_name='当时的不合格标记'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='wproduct',
|
||||||
|
name='coperation',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wp_coperation', to='wpm.operation', verbose_name='创建所关联操作'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='wproductflow',
|
||||||
|
name='coperation',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wpf_coperation', to='wpm.operation', verbose_name='创建所关联操作'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='operationmaterial',
|
||||||
|
name='material',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='om_material', to='mtm.material', verbose_name='可能产出的产品'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='wproductflow',
|
||||||
|
name='operation',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wpf_operation', to='wpm.operation', verbose_name='当前操作'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -96,6 +96,8 @@ class WProduct(CommonAModel):
|
||||||
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')
|
||||||
|
coperation = models.ForeignKey('wpm.operation', verbose_name='创建所关联操作',
|
||||||
|
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_coperation')
|
||||||
test = models.ForeignKey('qm.testrecord', verbose_name='当前检验',
|
test = models.ForeignKey('qm.testrecord', verbose_name='当前检验',
|
||||||
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_test')
|
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_test')
|
||||||
ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单',
|
ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单',
|
||||||
|
|
@ -144,7 +146,9 @@ class WproductFlow(CommonAModel):
|
||||||
|
|
||||||
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)
|
on_delete=models.SET_NULL, null=True, blank=True, related_name='wpf_operation')
|
||||||
|
coperation = models.ForeignKey('wpm.operation', verbose_name='创建所关联操作',
|
||||||
|
on_delete=models.SET_NULL, null=True, blank=True, related_name='wpf_coperation')
|
||||||
test = models.ForeignKey('qm.testrecord', verbose_name='当前检验',
|
test = models.ForeignKey('qm.testrecord', verbose_name='当前检验',
|
||||||
on_delete=models.SET_NULL, null=True, blank=True)
|
on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单',
|
ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单',
|
||||||
|
|
@ -183,7 +187,6 @@ class Operation(CommonADModel):
|
||||||
生产操作
|
生产操作
|
||||||
"""
|
"""
|
||||||
step = models.ForeignKey(Step, verbose_name='操作步骤', on_delete=models.CASCADE, null=True, blank=True)
|
step = models.ForeignKey(Step, verbose_name='操作步骤', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
use_scrap = models.BooleanField('是否使用的边角料', default=False)
|
|
||||||
remark = models.CharField('操作备注', max_length=200, null=True, blank=True)
|
remark = models.CharField('操作备注', max_length=200, null=True, blank=True)
|
||||||
is_submited = models.BooleanField('是否提交', default=False)
|
is_submited = models.BooleanField('是否提交', default=False)
|
||||||
|
|
||||||
|
|
@ -196,7 +199,7 @@ class OperationWproduct(BaseModel):
|
||||||
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
number = models.CharField('物品编号', 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)
|
||||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE, related_name='ow_subplan')
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE, related_name='ow_subplan')
|
||||||
|
ng_sign = models.PositiveSmallIntegerField('当时的不合格标记', choices= WProduct.ng_choices, null=True, blank=True)
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = (
|
unique_together = (
|
||||||
('operation','wproduct')
|
('operation','wproduct')
|
||||||
|
|
@ -209,7 +212,8 @@ class OperationMaterial(BaseModel):
|
||||||
type = models.IntegerField('类型', default=0, choices=SubprodctionMaterial.type_choices)
|
type = models.IntegerField('类型', default=0, choices=SubprodctionMaterial.type_choices)
|
||||||
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE)
|
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE)
|
||||||
|
|
||||||
material = models.ForeignKey(Material, verbose_name='可能产出的产品', on_delete=models.CASCADE, null=True, blank=True)
|
material = models.ForeignKey(Material, verbose_name='可能产出的产品', on_delete=models.CASCADE,
|
||||||
|
null=True, blank=True, related_name='om_material')
|
||||||
count = models.PositiveSmallIntegerField('消耗或产出数量', null=True, blank=True)
|
count = models.PositiveSmallIntegerField('消耗或产出数量', null=True, blank=True)
|
||||||
|
|
||||||
wmaterial = models.ForeignKey(WMaterial, verbose_name='关联的车间物料', on_delete=models.CASCADE, null=True, blank=True)
|
wmaterial = models.ForeignKey(WMaterial, verbose_name='关联的车间物料', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
|
|
@ -217,8 +221,12 @@ class OperationMaterial(BaseModel):
|
||||||
|
|
||||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联的子计划', on_delete=models.CASCADE, null=True, blank=True)
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联的子计划', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
batch = models.CharField('批次号', max_length=100, null=True, blank=True)
|
batch = models.CharField('批次号', max_length=100, null=True, blank=True)
|
||||||
|
use_scrap = models.BooleanField('是否使用的边角料', default=False)
|
||||||
|
|
||||||
#以下为冷加工下料清单所用字段
|
#以下为冷加工下料清单所用字段
|
||||||
|
from_material = models.ForeignKey(Material, verbose_name='源物料', on_delete=models.CASCADE,
|
||||||
|
null=True, blank=True, related_name='om_fmaterial')
|
||||||
|
from_batch = models.CharField('源批次', max_length=100, null=True, blank=True)
|
||||||
count_cut = models.PositiveIntegerField('切裁片数', default=0)
|
count_cut = models.PositiveIntegerField('切裁片数', default=0)
|
||||||
count_real = models.PositiveIntegerField('生产片数', default=0)
|
count_real = models.PositiveIntegerField('生产片数', default=0)
|
||||||
count_ok = models.PositiveIntegerField('成品数量', default=0)
|
count_ok = models.PositiveIntegerField('成品数量', default=0)
|
||||||
|
|
@ -226,6 +234,7 @@ class OperationMaterial(BaseModel):
|
||||||
count_podian = models.PositiveIntegerField('破点甩片', default=0)
|
count_podian = models.PositiveIntegerField('破点甩片', default=0)
|
||||||
count_hua = models.PositiveIntegerField('划伤甩片', default=0)
|
count_hua = models.PositiveIntegerField('划伤甩片', default=0)
|
||||||
count_other = models.PositiveIntegerField('其他甩片', default=0)
|
count_other = models.PositiveIntegerField('其他甩片', default=0)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = (
|
unique_together = (
|
||||||
('operation','material', 'batch')
|
('operation','material', 'batch')
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ class OperationCreateSerializer(serializers.Serializer):
|
||||||
class OperationUpdateSerializer(serializers.ModelSerializer):
|
class OperationUpdateSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Operation
|
model = Operation
|
||||||
fields =['use_scrap', 'remark']
|
fields =['remark']
|
||||||
|
|
||||||
class OperationInitSerializer(serializers.Serializer):
|
class OperationInitSerializer(serializers.Serializer):
|
||||||
step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID")
|
step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID")
|
||||||
|
|
@ -350,7 +350,7 @@ class OperationMaterialCreate1Serailizer(serializers.ModelSerializer):
|
||||||
wmaterial = serializers.PrimaryKeyRelatedField(required=True, queryset=WMaterial.objects.all())
|
wmaterial = serializers.PrimaryKeyRelatedField(required=True, queryset=WMaterial.objects.all())
|
||||||
class Meta:
|
class Meta:
|
||||||
model = OperationMaterial
|
model = OperationMaterial
|
||||||
fields = ['operation', 'wmaterial', 'count']
|
fields = ['operation', 'wmaterial', 'count', 'use_scrap']
|
||||||
|
|
||||||
def validate(self, attrs):
|
def validate(self, attrs):
|
||||||
if attrs['count'] <=0:
|
if attrs['count'] <=0:
|
||||||
|
|
@ -376,7 +376,7 @@ class OperationMaterialCreate2Serailizer(serializers.ModelSerializer):
|
||||||
subproduction_progress = serializers.PrimaryKeyRelatedField(required=True, queryset=SubProductionProgress.objects.all())
|
subproduction_progress = serializers.PrimaryKeyRelatedField(required=True, queryset=SubProductionProgress.objects.all())
|
||||||
class Meta:
|
class Meta:
|
||||||
model = OperationMaterial
|
model = OperationMaterial
|
||||||
fields = ['operation', 'subproduction_progress', 'count']
|
fields = ['operation', 'subproduction_progress', 'count', 'use_scrap']
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
subproduction_progress = validated_data['subproduction_progress']
|
subproduction_progress = validated_data['subproduction_progress']
|
||||||
|
|
@ -448,8 +448,8 @@ class WproductTicketListSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class CuttingListSerializer(serializers.ModelSerializer):
|
class CuttingListSerializer(serializers.ModelSerializer):
|
||||||
subproduction_plan_ = SubproductionPlanSimpleSerializer(source='subproduction_plan', read_only=True)
|
subproduction_plan_ = SubproductionPlanSimpleSerializer(source='subproduction_plan', read_only=True)
|
||||||
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
from_material_ = MaterialSimpleSerializer(source='from_material', read_only=True)
|
||||||
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
|
create_by_ = UserSimpleSerializer(source='operation.create_by', read_only=True)
|
||||||
class Meta:
|
class Meta:
|
||||||
model = OperationMaterial
|
model = OperationMaterial
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
@ -154,28 +154,28 @@ class WpmServies(object):
|
||||||
"""
|
"""
|
||||||
inputs = OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_IN)
|
inputs = OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_IN)
|
||||||
outputs = OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
outputs = OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
||||||
for i in inputs:
|
for i in outputs:
|
||||||
sp = i.subproduction_plan
|
if i.use_scrap: # 如果使用了边角料
|
||||||
i.count_cut = outputs.filter(subproduction_plan=sp).first().count
|
i.count_cut = 0
|
||||||
i.count_real = sp.count_real
|
i.from_material = SubprodctionMaterial.objects.filter(type=SubprodctionMaterial.SUB_MA_TYPE_IN,
|
||||||
i.count_ok = sp.count_ok
|
subproduction__subplan_subprod=i.subproduction_plan).first().material
|
||||||
wpfs = WproductFlow.objects.filter(subproduction_plan=sp, is_lastlog=True)
|
else:
|
||||||
i.count_qipao = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_QIPAO).count()
|
input_q = inputs.filter(subproduction_plan=i.subproduction_plan) # 同计划的消耗
|
||||||
i.count_podian = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_PODIAN).count()
|
i.from_material = input_q.first().material
|
||||||
i.count_hua = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_HUA).count()
|
count_cut = 0
|
||||||
i.count_other = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_OTHER).count()
|
from_batch = ''
|
||||||
i.is_cutting = True
|
for m in input_q:
|
||||||
i.save()
|
count_cut = count_cut + m.count
|
||||||
|
if from_batch and m.batch:
|
||||||
@classmethod
|
from_batch = from_batch + ';' + m.batch
|
||||||
def update_cutting_list_with_sp(cls, sp:SubProductionPlan):
|
else:
|
||||||
"""
|
from_batch = m.batch
|
||||||
根据子计划更新下料清单
|
i.count_cut = count_cut
|
||||||
"""
|
i.from_batch = from_batch
|
||||||
wpfs = WproductFlow.objects.filter(subproduction_plan=sp, is_lastlog=True)
|
wpfs = WproductFlow.objects.filter(subproduction_plan=i.subproduction_plan,
|
||||||
for i in OperationMaterial.objects.filter(subproduction_plan=sp, is_cutting=True):
|
is_lastlog=True, coperation=op)# 筛选本次操作下子计划的产品日志
|
||||||
i.count_real = sp.count_real
|
i.count_real = wpfs.count()
|
||||||
i.count_ok = sp.count_ok
|
i.count_ok = wpfs.filter(scrap_reason=None).count()
|
||||||
i.count_qipao = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_QIPAO).count()
|
i.count_qipao = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_QIPAO).count()
|
||||||
i.count_podian = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_PODIAN).count()
|
i.count_podian = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_PODIAN).count()
|
||||||
i.count_hua = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_HUA).count()
|
i.count_hua = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_HUA).count()
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from apps.wf.models import Workflow
|
from apps.wf.models import Workflow
|
||||||
from apps.wf.serializers import WorkflowSimpleSerializer
|
from apps.wf.serializers import WorkflowSimpleSerializer
|
||||||
from apps.wpm.filters import WMaterialFilterSet, WProductFilterSet
|
from apps.wpm.filters import CuttingFilterSet, WMaterialFilterSet, WProductFilterSet
|
||||||
from apps.wpm.models import OperationEquip, OperationWproduct, Pick, PickWproduct, WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem, WprouctTicket
|
from apps.wpm.models import OperationEquip, OperationWproduct, Pick, PickWproduct, WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem, WprouctTicket
|
||||||
|
|
||||||
from apps.wpm.serializers import CuttingListSerializer, OperationEquipListSerializer, OperationEquipUpdateSerializer, OperationMaterialCreate1ListSerailizer, OperationMaterialCreate1Serailizer, OperationMaterialCreate2ListSerailizer, OperationMaterialCreate2Serailizer, OperationMaterialCreate3Serializer, OperationMaterialListSerializer, OperationRecordDetailSerializer, OperationRecordListSerializer, OperationRecordSubmitSerializer, OperationUpdateSerializer, OperationWproductListSerializer, OperationCreateSerializer, OperationDetailSerializer, OperationListSerializer, PickHalfSerializer, PickHalfsSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, ScrapSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestFormInitSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer, WproductPutInsSerializer, WproductTicketListSerializer
|
from apps.wpm.serializers import CuttingListSerializer, OperationEquipListSerializer, OperationEquipUpdateSerializer, OperationMaterialCreate1ListSerailizer, OperationMaterialCreate1Serailizer, OperationMaterialCreate2ListSerailizer, OperationMaterialCreate2Serailizer, OperationMaterialCreate3Serializer, OperationMaterialListSerializer, OperationRecordDetailSerializer, OperationRecordListSerializer, OperationRecordSubmitSerializer, OperationUpdateSerializer, OperationWproductListSerializer, OperationCreateSerializer, OperationDetailSerializer, OperationListSerializer, PickHalfSerializer, PickHalfsSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, ScrapSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestFormInitSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer, WproductPutInsSerializer, WproductTicketListSerializer
|
||||||
|
|
@ -386,7 +386,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
obj.save()
|
obj.save()
|
||||||
WpmServies.add_wproduct_flow_log(obj, 'scrap')
|
WpmServies.add_wproduct_flow_log(obj, 'scrap')
|
||||||
if obj.step.process.id == 1: #如果是冷加工
|
if obj.step.process.id == 1: #如果是冷加工
|
||||||
WpmServies.update_cutting_list_with_sp(obj.subproduction_plan)
|
WpmServies.update_cutting_list_with_operation(obj.coperation)
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
# @action(methods=['get'], detail=False, perms_map={'get':'*'})
|
# @action(methods=['get'], detail=False, perms_map={'get':'*'})
|
||||||
|
|
@ -510,12 +510,13 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
||||||
owp['number'] = wpd.number
|
owp['number'] = wpd.number
|
||||||
owp['material'] = wpd.material
|
owp['material'] = wpd.material
|
||||||
owp['subproduction_plan'] = wpd.subproduction_plan
|
owp['subproduction_plan'] = wpd.subproduction_plan
|
||||||
|
owp['ng_sign'] = wpd.ng_sign
|
||||||
owps.append(OperationWproduct(**owp))
|
owps.append(OperationWproduct(**owp))
|
||||||
OperationWproduct.objects.bulk_create(owps)
|
OperationWproduct.objects.bulk_create(owps)
|
||||||
else:
|
else:
|
||||||
splans = WpmServies.get_subplans_queryset_from_wproducts(vdata['wproducts'])
|
splans = WpmServies.get_subplans_queryset_from_wproducts(vdata['wproducts'])
|
||||||
# 查询需要填写的自定义表格
|
# 查询需要填写的自定义表格
|
||||||
forms = RecordForm.objects.filter(step=step, type=RecordForm.RF_TYPE_DO)
|
forms = RecordForm.objects.filter(step=step, type=RecordForm.RF_TYPE_DO, enabled=True)
|
||||||
for i in forms:
|
for i in forms:
|
||||||
opr = OperationRecord()
|
opr = OperationRecord()
|
||||||
opr.operation = op
|
opr.operation = op
|
||||||
|
|
@ -555,11 +556,22 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
||||||
step = op.step
|
step = op.step
|
||||||
if op.is_submited:
|
if op.is_submited:
|
||||||
raise exceptions.APIException('该操作已提交')
|
raise exceptions.APIException('该操作已提交')
|
||||||
|
# 校验消耗产出是否正确填写
|
||||||
|
omis = OperationMaterial.objects.filter(operation=op,
|
||||||
|
type=SubprodctionMaterial.SUB_MA_TYPE_IN)
|
||||||
|
sps_omi_l = omis.values_list('subproduction_plan', flat=True)
|
||||||
|
omos = OperationMaterial.objects.filter(operation=op,
|
||||||
|
type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
||||||
|
sps_omo_l = omos.filter(use_scrap=False).values_list('subproduction_plan', flat=True)
|
||||||
|
if set(list(sps_omi_l)) == set(list(sps_omo_l)):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise exceptions.APIException('消耗与产出不一致')
|
||||||
# 检查自定义表单填写
|
# 检查自定义表单填写
|
||||||
if OperationRecord.objects.filter(operation=op, is_filled=False).exists():
|
if OperationRecord.objects.filter(operation=op, is_filled=False).exists():
|
||||||
raise exceptions.APIException('存在自定义表单未填写')
|
raise exceptions.APIException('存在自定义表单未填写')
|
||||||
# 更新物料消耗进度
|
# 更新物料消耗进度
|
||||||
for i in OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_IN):
|
for i in omis:
|
||||||
# 更新车间物料
|
# 更新车间物料
|
||||||
i_wmat = i.wmaterial
|
i_wmat = i.wmaterial
|
||||||
i_wmat.count = i_wmat.count- i.count
|
i_wmat.count = i_wmat.count- i.count
|
||||||
|
|
@ -570,7 +582,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
||||||
spp.count_real = spp.count_real + i.count
|
spp.count_real = spp.count_real + i.count
|
||||||
spp.save()
|
spp.save()
|
||||||
# 更新产出
|
# 更新产出
|
||||||
for i in OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT):
|
for i in omos:
|
||||||
if not i.subproduction_progress.is_main:
|
if not i.subproduction_progress.is_main:
|
||||||
# 更新车间物料产出情况
|
# 更新车间物料产出情况
|
||||||
ins, _ = WMaterial.objects.get_or_create(subproduction_plan=i.subproduction_plan, material=i.material)
|
ins, _ = WMaterial.objects.get_or_create(subproduction_plan=i.subproduction_plan, material=i.material)
|
||||||
|
|
@ -607,24 +619,23 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
||||||
|
|
||||||
elif step.type == Step.STEP_TYPE_DIV:
|
elif step.type == Step.STEP_TYPE_DIV:
|
||||||
# 更新物料产出情况
|
# 更新物料产出情况
|
||||||
outputs = OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
if not omos.exists():
|
||||||
if not outputs.exists():
|
|
||||||
raise exceptions.APIException('请选择物料产出')
|
raise exceptions.APIException('请选择物料产出')
|
||||||
for i in outputs:
|
for i in omos:
|
||||||
if i.subproduction_progress.is_main:
|
if i.subproduction_progress.is_main:
|
||||||
newstep, _ = WpmServies.get_next_step(i.subproduction_plan, step)
|
newstep, _ = WpmServies.get_next_step(i.subproduction_plan, step)
|
||||||
wpr = dict(material=i.material, step=newstep,
|
wpr = dict(material=i.material, step=newstep,
|
||||||
act_state=WProduct.WPR_ACT_STATE_DOWAIT, remark='',
|
act_state=WProduct.WPR_ACT_STATE_DOWAIT, remark='',
|
||||||
subproduction_plan=i.subproduction_plan, create_by=request.user)
|
subproduction_plan=i.subproduction_plan,
|
||||||
|
create_by=request.user, coperation=op)
|
||||||
for x in range(i.count):
|
for x in range(i.count):
|
||||||
ins = WProduct.objects.create(**wpr)
|
ins = WProduct.objects.create(**wpr)
|
||||||
# 添加日志
|
# 添加日志
|
||||||
WpmServies.add_wproduct_flow_log(ins, 'operation_submit')
|
WpmServies.add_wproduct_flow_log(ins, 'wproduct_create')
|
||||||
# 更新进度
|
# 更新进度
|
||||||
WpmServies.update_subproduction_progress_main(sp=i.subproduction_plan)
|
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 = omos.filter(subproduction_progress__is_main=True)
|
||||||
subproduction_progress__is_main=True)
|
|
||||||
if len(oms_w) == 1:
|
if len(oms_w) == 1:
|
||||||
oms_w = oms_w[0]
|
oms_w = oms_w[0]
|
||||||
# 校验单片数量是否正确, 暂时未写
|
# 校验单片数量是否正确, 暂时未写
|
||||||
|
|
@ -640,8 +651,9 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
||||||
# 更新子计划进度
|
# 更新子计划进度
|
||||||
WpmServies.update_subproduction_progress_main(sp=oms_w.subproduction_plan)
|
WpmServies.update_subproduction_progress_main(sp=oms_w.subproduction_plan)
|
||||||
wproduct.create_by = request.user
|
wproduct.create_by = request.user
|
||||||
|
wproduct.coperation = op
|
||||||
wproduct.save()
|
wproduct.save()
|
||||||
WpmServies.add_wproduct_flow_log(wproduct, 'operation_submit')
|
WpmServies.add_wproduct_flow_log(wproduct, 'wproduct_create')
|
||||||
# 隐藏原半成品
|
# 隐藏原半成品
|
||||||
wps = WProduct.objects.filter(ow_wproduct__operation = op)
|
wps = WProduct.objects.filter(ow_wproduct__operation = op)
|
||||||
wps.update(is_hidden=True, child=wproduct, update_by=request.user, update_time=timezone.now())
|
wps.update(is_hidden=True, child=wproduct, update_by=request.user, update_time=timezone.now())
|
||||||
|
|
@ -793,9 +805,9 @@ class CuttingListViewSet(ListModelMixin, GenericViewSet):
|
||||||
"""
|
"""
|
||||||
perms_map={'*':'*'}
|
perms_map={'*':'*'}
|
||||||
queryset = OperationMaterial.objects.select_related('operation',
|
queryset = OperationMaterial.objects.select_related('operation',
|
||||||
'subproduction_plan', 'material', 'create_by').filter(operation__step__process__id=1)
|
'subproduction_plan', 'material', 'operation__create_by').filter(operation__step__id=1, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
||||||
serializer_class = CuttingListSerializer
|
serializer_class = CuttingListSerializer
|
||||||
filterset_fields = ['operation', 'subproduction_plan', 'material']
|
filterset_class = CuttingFilterSet
|
||||||
ordering_fields = ['id']
|
ordering_fields = ['id']
|
||||||
ordering = ['-id']
|
ordering = ['-id']
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue