Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop
This commit is contained in:
commit
7cbbdfaf48
|
|
@ -1,5 +1,6 @@
|
|||
import request from '@/utils/request'
|
||||
//物料
|
||||
|
||||
export function getMaterialList(query) {
|
||||
return request({
|
||||
url: '/mtm/material/',
|
||||
|
|
@ -34,6 +35,36 @@ export function deleteMaterial(id, data) {
|
|||
data
|
||||
})
|
||||
}
|
||||
//产品分解
|
||||
export function getsubproducationList(query) {
|
||||
return request({
|
||||
url: '/mtm/subproducation/',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
export function createsubproducation(data) {
|
||||
return request({
|
||||
url: '/mtm/subproducation/',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function updatesubproducation(id, data) {
|
||||
return request({
|
||||
url: `/mtm/subproducation/${id}/`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
export function deletesubproducation(id, data) {
|
||||
return request({
|
||||
url: `/mtm/subproducation/${id}/`,
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
//工序
|
||||
export function getProcessList(query) {
|
||||
return request({
|
||||
|
|
@ -64,7 +95,16 @@ export function deleteProcess(id, data) {
|
|||
})
|
||||
}
|
||||
//子工序
|
||||
export function getStepList(id) {
|
||||
export function getStepList(query) {
|
||||
return request({
|
||||
url: `/mtm/step/`,
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export function getStepLists(id) {
|
||||
return request({
|
||||
url: `/mtm/process/${id}/steps/`,
|
||||
method: 'get'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
//生产排程
|
||||
export function getProductionplanList(query) {
|
||||
return request({
|
||||
url: 'pm/productionplan/',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
export function createProductionplan(data) {
|
||||
return request({
|
||||
url: 'pm/productionplan/',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -87,3 +87,10 @@ export function deleteOrder(id, data) {
|
|||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function getordertoplan() {
|
||||
return request({
|
||||
url: '/sam/order/toplan/',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
|
@ -130,6 +130,34 @@ export const asyncRoutes = [
|
|||
meta: { title: '产品管理', icon: 'example', perms: ['vendor_manage'] }
|
||||
},
|
||||
]
|
||||
}
|
||||
,
|
||||
{
|
||||
path: '/pm',
|
||||
component: Layout,
|
||||
redirect: '/pm/plan',
|
||||
name: 'pm',
|
||||
meta: { title: '生产管理', icon: 'example', perms: ['equipment_set'] },
|
||||
children: [
|
||||
{
|
||||
path: 'plan',
|
||||
name: 'plan',
|
||||
component: () => import('@/views/pm/plan'),
|
||||
meta: { title: '生产计划管理', icon: 'example', perms: ['index_manage'] }
|
||||
},
|
||||
{
|
||||
path: 'resources',
|
||||
name: 'resources',
|
||||
component: () => import('@/views/pm/resources'),
|
||||
meta: { title: '生产资源配置', icon: 'example', perms: ['index_manage'] }
|
||||
},
|
||||
{
|
||||
path: 'testitem',
|
||||
name: 'testitem',
|
||||
component: () => import('@/views/pm/plan'),
|
||||
meta: { title: '生产作业管理', icon: 'example', perms: ['index_manage'] }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/em',
|
||||
|
|
@ -233,6 +261,13 @@ export const asyncRoutes = [
|
|||
name: 'warehouse',
|
||||
component: () => import('@/views/inm/warehouse'),
|
||||
meta: { title: '仓库', icon: 'example', perms: ['index_manage'] }
|
||||
},
|
||||
{
|
||||
path: 'materialbatch/:id',
|
||||
name: 'MaterialBatch',
|
||||
component: () => import('@/views/inm/materialbatch'),
|
||||
meta: { title: '仓库物料', perms: ['vendor_manage'] },
|
||||
hidden: true
|
||||
}
|
||||
,
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,178 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-card>
|
||||
<div>
|
||||
<el-input
|
||||
v-model="listQuery.search"
|
||||
placeholder="仓库名称/仓库编号"
|
||||
style="width: 300px"
|
||||
class="filter-item"
|
||||
@keyup.enter.native="handleFilter"
|
||||
/>
|
||||
<el-button
|
||||
class="filter-item"
|
||||
type="primary"
|
||||
icon="el-icon-search"
|
||||
@click="handleFilter"
|
||||
>搜索</el-button
|
||||
>
|
||||
<el-button
|
||||
class="filter-item"
|
||||
type="primary"
|
||||
icon="el-icon-refresh-left"
|
||||
@click="resetFilter"
|
||||
>重置</el-button
|
||||
>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card style="margin-top: 10px">
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="warehouseList.results"
|
||||
border
|
||||
fit
|
||||
stripe
|
||||
highlight-current-row
|
||||
max-height="600"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column label="物料名称">
|
||||
<template slot-scope="scope">{{ scope.row.name }}</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="物料批次">
|
||||
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="入库数量">
|
||||
<template slot-scope="scope">{{ scope.row.place }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="物料有效期">
|
||||
<template slot-scope="scope">{{ scope.row.place }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="入库时间">
|
||||
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
label="操作"
|
||||
width="220px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
|
||||
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_delete'])"
|
||||
type="danger"
|
||||
@click="handleDelete(scope)"
|
||||
>删除</el-link
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="warehouseList.count > 0"
|
||||
:total="warehouseList.count"
|
||||
:page.sync="listQuery.page"
|
||||
:limit.sync="listQuery.page_size"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</el-card>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getWarehouseList, deleteWarehouse } from "@/api/inm";
|
||||
import checkPermission from "@/utils/permission";
|
||||
|
||||
|
||||
import { genTree } from "@/utils";
|
||||
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
||||
const defaultewarehouse = {
|
||||
};
|
||||
export default {
|
||||
components: { Pagination },
|
||||
data() {
|
||||
return {
|
||||
warehouse: defaultewarehouse,
|
||||
warehouseList: {
|
||||
count: 0,
|
||||
},
|
||||
options: [{
|
||||
value: 0,
|
||||
label: '运转正常'
|
||||
}, {
|
||||
value: 1,
|
||||
label: '停用'
|
||||
}, {
|
||||
value: 2,
|
||||
label: '报废'
|
||||
}],
|
||||
listQuery: {
|
||||
page: 1,
|
||||
page_size: 20,
|
||||
},
|
||||
keeperOptions:[],
|
||||
depOptions:[],
|
||||
listLoading: true,
|
||||
dialogVisible: false,
|
||||
dialogType: "new",
|
||||
rule1: {
|
||||
name: [{ required: true, message: "请输入", trigger: "blur" }],
|
||||
number: [{ required: true, message: "请输入", trigger: "blur" }],
|
||||
place: [{ required: true, message: "请输入", trigger: "blur" }],
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
checkPermission,
|
||||
//设备列表
|
||||
getList() {
|
||||
this.listLoading = true;
|
||||
getWarehouseList(this.listQuery).then((response) => {
|
||||
if (response.data) {
|
||||
this.warehouseList = response.data;
|
||||
}
|
||||
this.listLoading = false;
|
||||
});
|
||||
},
|
||||
|
||||
handleMaterial(scope){
|
||||
alert(1)
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1;
|
||||
this.getList();
|
||||
},
|
||||
resetFilter() {
|
||||
this.listQuery = {
|
||||
page: 1,
|
||||
page_size: 20,
|
||||
}
|
||||
this.getList();
|
||||
},
|
||||
|
||||
handleDelete(scope) {
|
||||
this.$confirm("确认删除?", "警告", {
|
||||
confirmButtonText: "确认",
|
||||
cancelButtonText: "取消",
|
||||
type: "error",
|
||||
})
|
||||
.then(async () => {
|
||||
await deleteWarehouse(scope.row.id);
|
||||
this.getList();
|
||||
this.$message.success("成功");
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -61,7 +61,11 @@
|
|||
width="220px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
@click="handleMaterial(scope)"
|
||||
>查看物料</el-link
|
||||
>
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
@click="handleEdit(scope)"
|
||||
|
|
@ -173,8 +177,10 @@ export default {
|
|||
this.listLoading = false;
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
//跳转到该仓库的物料表
|
||||
handleMaterial(scope){
|
||||
this.$router.push({name: "MaterialBatch", params: { id: scope.row.id }, })
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1;
|
||||
this.getList();
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
|
||||
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="过程记录">
|
||||
|
||||
<el-card>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="6" >
|
||||
<el-card style="margin-top: 10px">
|
||||
<el-card >
|
||||
<div slot="header" class="clearfix">
|
||||
<span style="font-size: 16px;
|
||||
font-weight: 700;
|
||||
">过程记录表</span>
|
||||
</div>
|
||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||
>新增</el-button>
|
||||
<el-table
|
||||
|
||||
:data="recordformList.results"
|
||||
border
|
||||
fit
|
||||
|
|
@ -21,34 +22,30 @@
|
|||
v-el-height-adaptive-table="{bottomOffset: 50}"
|
||||
@current-change="handleCurrentChange"
|
||||
>
|
||||
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column label="表名称">
|
||||
<template slot-scope="scope">{{ scope.row.name }}</template>
|
||||
|
||||
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
label="操作"
|
||||
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
|
||||
<el-link
|
||||
v-if="checkPermission(['material_update'])"
|
||||
@click="handleLook(scope)"
|
||||
>查看</el-link>
|
||||
<el-link
|
||||
v-if="checkPermission(['material_update'])"
|
||||
@click="handleEdit(scope)"
|
||||
>编辑</el-link
|
||||
>
|
||||
>编辑</el-link>
|
||||
<el-link
|
||||
v-if="checkPermission(['material_delete'])"
|
||||
type="danger"
|
||||
@click="handleDelete(scope)"
|
||||
>删除</el-link
|
||||
>
|
||||
>删除</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
<el-dialog
|
||||
:visible.sync="dialogVisible"
|
||||
|
|
@ -74,11 +71,80 @@
|
|||
<el-button type="primary" @click="recordformconfirm('Forms')">确认</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
:model="tableForm"
|
||||
:visible.sync="dialogVisibleForm"
|
||||
:title="tableForm.name">
|
||||
<el-form
|
||||
label-width="80px"
|
||||
label-position="right"
|
||||
>
|
||||
<el-row v-for="(item,$index) in fieldList.results" :key="$index">
|
||||
<el-form-item v-if="item.field_type==='string'" :label="item.field_name" >
|
||||
<el-input placeholder="请输入" v-model="item.sort"/>
|
||||
</el-form-item>
|
||||
<el-form-item v-else-if="item.field_type==='int'" :label="item.field_name">
|
||||
<el-input type="number" placeholder="请输入" v-model="item.sort"/>
|
||||
</el-form-item>
|
||||
<el-form-item v-else-if="item.field_type==='float'" :label="item.field_name">
|
||||
<el-input type="number" placeholder="请输入" v-model="item.sort"/>
|
||||
</el-form-item>
|
||||
<el-form-item v-else-if="item.field_type==='date'" :label="item.field_name">
|
||||
<el-date-picker
|
||||
v-model="item.create_time"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
value-format="yyyy-MM-dd"
|
||||
style="width:100%"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item v-else-if="item.field_type==='datetime'" :label="item.field_name">
|
||||
<el-date-picker
|
||||
v-model="item.create_time"
|
||||
type="datetime"
|
||||
placeholder="选择日期"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
style="width:100%"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item v-else-if="item.field_type==='select'" :label="item.field_name">
|
||||
<el-select style="width: 100%" v-model="item.sort" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="item1 in item.field_choice"
|
||||
:key="item1"
|
||||
:label="item1"
|
||||
:value="item1">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-else-if="item.field_type==='selects'" :label="item.field_name">
|
||||
<el-select style="width: 100%" v-model="optio" multiple placeholder="请选择">
|
||||
<el-option
|
||||
v-for="item1 in item.field_choice"
|
||||
:key="item1"
|
||||
:label="item1"
|
||||
:value="item1">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<!--<div style="text-align: right">-->
|
||||
<!--<el-button type="danger">取消</el-button>-->
|
||||
<!--<el-button type="primary">确认</el-button>-->
|
||||
<!--</div>-->
|
||||
</el-dialog>
|
||||
</el-card>
|
||||
|
||||
</el-col>
|
||||
<el-col :span="18" >
|
||||
<el-card class="box-card">
|
||||
<el-card >
|
||||
<div slot="header" class="clearfix">
|
||||
<span style="font-size: 16px;
|
||||
font-weight: 700;
|
||||
">记录字段</span>
|
||||
</div>
|
||||
<el-button type="primary" icon="el-icon-plus" @click="handlefieldCreate"
|
||||
>新增</el-button>
|
||||
<el-table
|
||||
|
|
@ -105,9 +171,7 @@
|
|||
<el-table-column label="字段标识">
|
||||
<template slot-scope="scope">{{ scope.row.field_key }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="布尔类型显示名">
|
||||
<template slot-scope="scope">{{ scope.row.boolean_field_display }}</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="选项显示名">
|
||||
<template slot-scope="scope">{{ scope.row.field_choice }}</template>
|
||||
</el-table-column>
|
||||
|
|
@ -135,17 +199,8 @@
|
|||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
<el-dialog
|
||||
:visible.sync="dialogVisible1"
|
||||
:title="dialogType1 === 'edit' ? '编辑表格字段' : '新增表格字段'"
|
||||
>
|
||||
<el-form
|
||||
ref="Form"
|
||||
:model="field"
|
||||
label-width="80px"
|
||||
label-position="right"
|
||||
>
|
||||
|
||||
<el-dialog :visible.sync="dialogVisible1" :title="dialogType1 === 'edit' ? '编辑表格字段' : '新增表格字段'">
|
||||
<el-form ref="Form" :model="field" label-width="80px" label-position="right">
|
||||
<el-form-item label="字段类型" prop="field_type">
|
||||
<el-select style="width: 100%" v-model="field.field_type" placeholder="请选择">
|
||||
<el-option
|
||||
|
|
@ -157,36 +212,28 @@
|
|||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="字段标识" prop="field_key">
|
||||
<el-input v-model="field.field_key" placeholder="字段标识" />
|
||||
<el-input v-model="field.field_key" placeholder="字段标识" onkeyup="value=value.replace(/[^A-Za-z_\/]/ig,'')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="字段名称" prop="field_name">
|
||||
<el-input v-model="field.field_name" placeholder="字段名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="布尔类型显示名" prop="boolean_field_display">
|
||||
<vue-json-editor
|
||||
v-model="field.boolean_field_display"
|
||||
:showBtns="false"
|
||||
:mode="'code'"
|
||||
lang="zh"
|
||||
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="选项" prop="field_choice">
|
||||
|
||||
<vue-json-editor
|
||||
v-model="field.field_choice"
|
||||
:showBtns="false"
|
||||
:mode="'code'"
|
||||
lang="zh"
|
||||
|
||||
/>
|
||||
<el-form-item label="选项" v-show="field.field_type=='radio'||field.field_type=='checkbox'||field.field_type=='select'||field.field_type=='selects'">
|
||||
<el-button @click.prevent="addDomain" style="border: none;">
|
||||
<i class="el-icon-circle-plus-outline"></i>
|
||||
<span style="font-size:14px;">添加</span>
|
||||
</el-button>
|
||||
<el-row v-for="(domain, $index) in field_choice" :key=domain+$index style="margin-bottom: 10px">
|
||||
<el-col :span="20">
|
||||
<el-input v-model="field_choice[$index]" auto-complete="off"></el-input>
|
||||
</el-col>
|
||||
<el-col :span="3" style="text-align: center" v-if="$index!==0">
|
||||
<i class="el-icon-remove-outline" @click.prevent="removeDomain($index,'1')" style="color: red;font-size: 16px;"></i>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input v-model="field.sort" placeholder="排序" />
|
||||
<el-input-number v-model="field.sort" :min="1" placeholder="排序"></el-input-number>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
|
||||
</el-form>
|
||||
<div style="text-align: right">
|
||||
<el-button type="danger" @click="dialogVisible1 = false">取消</el-button>
|
||||
|
|
@ -194,23 +241,27 @@
|
|||
</div>
|
||||
</el-dialog>
|
||||
</el-card>
|
||||
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
</el-card>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getStep,getrecordformList,createrecordform,updaterecordform,deleterecordform,getrffieldList,createrffield,updaterffield,
|
||||
deleterffield} from "@/api/mtm";
|
||||
|
||||
import vueJsonEditor from 'vue-json-editor'
|
||||
<script>
|
||||
|
||||
import checkPermission from "@/utils/permission";
|
||||
import { getEquipmentAll } from "@/api/equipment";
|
||||
import { upUrl, upHeaders } from "@/api/file";
|
||||
import {getrecordformList,createrecordform,updaterecordform,deleterecordform,getrffieldList,createrffield,updaterffield,
|
||||
deleterffield} from "@/api/mtm";
|
||||
import vueJsonEditor from 'vue-json-editor'
|
||||
import { genTree } from "@/utils";
|
||||
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
||||
const defaultstep = {
|
||||
name: "",
|
||||
number: "",
|
||||
};
|
||||
|
||||
const defaultrecordform = {
|
||||
|
||||
};
|
||||
|
|
@ -218,17 +269,40 @@
|
|||
|
||||
};
|
||||
export default {
|
||||
components: { vueJsonEditor },
|
||||
|
||||
components: { Pagination,vueJsonEditor },
|
||||
data() {
|
||||
return {
|
||||
|
||||
step: defaultstep,
|
||||
stepList:[],
|
||||
upHeaders: upHeaders(),
|
||||
upUrl: upUrl(),
|
||||
fileList:[],
|
||||
listLoading: true,
|
||||
dialogVisibles: false,
|
||||
dialogVisibleForm: false,
|
||||
dialogTypes: "new",
|
||||
field: {
|
||||
field_type:'',
|
||||
field_key:'',
|
||||
field_name:'',
|
||||
sort:'',
|
||||
field_choice:[""],
|
||||
},
|
||||
field_choice:[''],
|
||||
options:[],
|
||||
optio:[],
|
||||
rule1: {
|
||||
name: [{ required: true, message: "请输入", trigger: "blur" }],
|
||||
number: [{ required: true, message: "请输入", trigger: "blur" }],
|
||||
},
|
||||
recordform: defaultrecordform,
|
||||
field: defaultfield,
|
||||
dialogType: "new",
|
||||
dialogVisible:false,
|
||||
dialogType1: "new",
|
||||
dialogVisible1:false,
|
||||
tableForm:{
|
||||
name:'',
|
||||
},
|
||||
listQueryrecordform: {
|
||||
page: 1,
|
||||
page_size: 20,
|
||||
|
|
@ -244,78 +318,81 @@
|
|||
page_size: 20,
|
||||
},
|
||||
options_: {
|
||||
'string':'字符串',
|
||||
'int':'整型',
|
||||
'float': '浮点',
|
||||
'boolean':'布尔',
|
||||
'string':'文本',
|
||||
'int':'整数',
|
||||
'float':'小数',
|
||||
'date': '日期',
|
||||
'datetime': '日期时间',
|
||||
'radio': '单选',
|
||||
'checkbox': '多选',
|
||||
'select': '单选下拉',
|
||||
'selects': '多选下拉',
|
||||
'textarea': '文本域'
|
||||
'select': '单选',
|
||||
'selects': '多选',
|
||||
},
|
||||
fieldtypeoptions: [{
|
||||
value: 'string',
|
||||
label: '字符串'
|
||||
label: '文本'
|
||||
},
|
||||
{
|
||||
value: 'int',
|
||||
label: '整型'
|
||||
label: '整数'
|
||||
},
|
||||
{
|
||||
value: 'float',
|
||||
label: '浮点'
|
||||
},
|
||||
{
|
||||
value: 'boolean',
|
||||
label: '布尔'
|
||||
label: '小数'
|
||||
},
|
||||
{
|
||||
value: 'date',
|
||||
label: '日期'
|
||||
},
|
||||
{
|
||||
value: 'time',
|
||||
label: '时间'
|
||||
},
|
||||
{
|
||||
value: 'datetime',
|
||||
label: '日期时间'
|
||||
},
|
||||
{
|
||||
value: 'radio',
|
||||
value: 'select',
|
||||
label: '单选'
|
||||
},
|
||||
{
|
||||
value: 'checkbox',
|
||||
label: '多选'
|
||||
},
|
||||
{
|
||||
value: 'select',
|
||||
label: '单选下拉'
|
||||
},
|
||||
{
|
||||
value: 'selects',
|
||||
label: '多选下拉'
|
||||
},
|
||||
{
|
||||
value: 'textarea',
|
||||
label: '文本域'
|
||||
label: '多选'
|
||||
}
|
||||
],
|
||||
typeoptions: [{
|
||||
value: 1,
|
||||
label: '生产记录'
|
||||
}],
|
||||
|
||||
};
|
||||
},
|
||||
computed: {},
|
||||
watch: {
|
||||
|
||||
},
|
||||
watch: {},
|
||||
created() {
|
||||
|
||||
|
||||
this.step.process = this.$route.params.id;
|
||||
this.recordformLists();
|
||||
this.material = this.$route.params.id;
|
||||
|
||||
},
|
||||
methods: {
|
||||
//添加字段选项
|
||||
addDomain() {
|
||||
this.field_choice.push('')
|
||||
},
|
||||
//删除字段选项
|
||||
removeDomain(index){
|
||||
this.field_choice.splice(index, 1)
|
||||
},
|
||||
handleLook(scope){
|
||||
debugger;
|
||||
console.log(scope);
|
||||
this.dialogVisibleForm = true;
|
||||
this.tableForm = Object.assign({}, scope.row); // copy obj
|
||||
this.formID=this.tableForm.id;
|
||||
this.fieldLists();
|
||||
},
|
||||
checkPermission,
|
||||
|
||||
|
||||
|
||||
handleCurrentChange(row){
|
||||
this.formID=row.id;
|
||||
this.fieldLists();
|
||||
|
|
@ -323,9 +400,8 @@
|
|||
},
|
||||
recordformLists()
|
||||
{
|
||||
this.listQueryrecordform.material = this.material;
|
||||
console.log(this.materialid)
|
||||
this.listQueryrecordform.type = 2;
|
||||
this.listQueryrecordform.step=this.stepid;
|
||||
this.listQueryrecordform.type=2;
|
||||
getrecordformList(this.listQueryrecordform).then((response) => {
|
||||
if (response.data) {
|
||||
this.recordformList = response.data;
|
||||
|
|
@ -339,10 +415,13 @@
|
|||
getrffieldList(this.listQueryfield).then((response) => {
|
||||
if (response.data) {
|
||||
this.fieldList = response.data;
|
||||
debugger;
|
||||
console.log(this.fieldList)
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
//新增记录表
|
||||
handleCreate() {
|
||||
this.recordform = Object.assign({}, defaultrecordform);
|
||||
this.dialogType = "new";
|
||||
|
|
@ -351,7 +430,10 @@
|
|||
this.$refs["Forms"].clearValidate();
|
||||
});
|
||||
},
|
||||
//新增字段
|
||||
handlefieldCreate() {
|
||||
|
||||
this.field_choice = [''];
|
||||
this.field = Object.assign({}, defaultfield);
|
||||
this.dialogType1 = "new";
|
||||
this.dialogVisible1 = true;
|
||||
|
|
@ -369,6 +451,7 @@
|
|||
},
|
||||
handlefieldEdit(scope) {
|
||||
this.field = Object.assign({}, scope.row); // copy obj
|
||||
this.field_choice = this.field.field_choice;
|
||||
this.dialogType1 = "edit";
|
||||
this.dialogVisible1 = true;
|
||||
this.$nextTick(() => {
|
||||
|
|
@ -410,7 +493,7 @@
|
|||
if (valid) {
|
||||
const isEdit = this.dialogType === "edit";
|
||||
if (isEdit) {
|
||||
this.recordform.material=this.material;
|
||||
this.recordform.step=this.stepid;
|
||||
this.recordform.type=2;
|
||||
updaterecordform(this.recordform.id, this.recordform).then((res) => {
|
||||
if (res.code >= 200) {
|
||||
|
|
@ -420,7 +503,7 @@
|
|||
}
|
||||
});
|
||||
} else {
|
||||
this.recordform.material=this.material;
|
||||
this.recordform.step=this.stepid
|
||||
this.recordform.type=2;
|
||||
createrecordform(this.recordform).then((res) => {
|
||||
if (res.code >= 200) {
|
||||
|
|
@ -440,8 +523,8 @@
|
|||
if (valid) {
|
||||
const isEdit = this.dialogType1 === "edit";
|
||||
if (isEdit) {
|
||||
this.field.form=this.formID
|
||||
|
||||
this.field.form=this.formID;
|
||||
this.field.field_choice = this.field_choice;
|
||||
updaterffield(this.field.id, this.field).then((res) => {
|
||||
if (res.code >= 200) {
|
||||
this.fieldLists()
|
||||
|
|
@ -450,8 +533,8 @@
|
|||
}
|
||||
});
|
||||
} else {
|
||||
this.field.form=this.formID
|
||||
|
||||
this.field.form=this.formID;
|
||||
this.field.field_choice = this.field_choice;
|
||||
createrffield(this.field).then((res) => {
|
||||
if (res.code >= 200) {
|
||||
this.fieldLists()
|
||||
|
|
|
|||
|
|
@ -15,8 +15,7 @@
|
|||
fit
|
||||
stripe
|
||||
highlight-current-row
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 50}"
|
||||
|
||||
@current-change="handleCurrentChange">
|
||||
|
||||
<el-table-column type="index" width="50" />
|
||||
|
|
@ -30,9 +29,6 @@
|
|||
</el-table>
|
||||
|
||||
</el-card>
|
||||
|
||||
</el-col>
|
||||
<el-col :span="18" >
|
||||
<el-card >
|
||||
|
||||
<el-descriptions class="margin-top" title="产品信息" :column="3" border>
|
||||
|
|
@ -56,7 +52,9 @@
|
|||
</el-descriptions>
|
||||
|
||||
</el-card>
|
||||
<el-card class="box-card">
|
||||
</el-col>
|
||||
<el-col :span="18" >
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span style="font-size: 16px;
|
||||
font-weight: 700;
|
||||
|
|
@ -68,6 +66,87 @@
|
|||
</el-step>
|
||||
</el-steps>
|
||||
</el-card>
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span style="font-size: 16px;
|
||||
font-weight: 700;
|
||||
">生产分解</span>
|
||||
</div>
|
||||
<el-button type="primary" icon="el-icon-plus" @click="handlesubproducationCreate"
|
||||
>新增</el-button>
|
||||
<el-table
|
||||
|
||||
:data="subproducationData"
|
||||
border
|
||||
fit
|
||||
stripe
|
||||
@current-change="handlespChange"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column label="物料编号">
|
||||
<template slot-scope="scope">{{scope.row.name}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单位消耗量">
|
||||
<template slot-scope="scope">{{ scope.row.sort }}</template>
|
||||
</el-table-column>
|
||||
|
||||
|
||||
|
||||
<el-table-column
|
||||
align="center"
|
||||
label="操作"
|
||||
width="220px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
|
||||
<el-link
|
||||
v-if="checkPermission(['material_update'])"
|
||||
@click="handlesubproducationEdit(scope)"
|
||||
>编辑</el-link
|
||||
>
|
||||
<el-link
|
||||
v-if="checkPermission(['material_delete'])"
|
||||
type="danger"
|
||||
@click="handlesubproducationDelete(scope)"
|
||||
>删除</el-link
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-dialog
|
||||
:visible.sync="dialogVisiblesp"
|
||||
:title="dialogTypesp === 'edit' ? '编辑生产分解' : '新增生产分解'"
|
||||
>
|
||||
<el-form
|
||||
ref="Formsp"
|
||||
:model="subproducation"
|
||||
label-width="80px"
|
||||
label-position="right"
|
||||
>
|
||||
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="subproducation.name" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="subproducation.sort"
|
||||
:min="-2147483648"
|
||||
:max="2147483647"
|
||||
></el-input-number>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
|
||||
|
||||
</el-form>
|
||||
<div style="text-align: right">
|
||||
<el-button type="danger" @click="dialogVisible1 = false">取消</el-button>
|
||||
<el-button type="primary" @click="subproducationfirm('Formsp')">确认</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-card>
|
||||
|
||||
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="输入物料">
|
||||
|
|
@ -272,7 +351,9 @@
|
|||
<el-table-column label="子工序名称">
|
||||
<template slot-scope="scope">{{ scope.row.step_.name }}</template>
|
||||
</el-table-column >
|
||||
|
||||
<el-table-column label="备注">
|
||||
<template slot-scope="scope">{{ scope.row.remark }}</template>
|
||||
</el-table-column >
|
||||
|
||||
<el-table-column
|
||||
align="center"
|
||||
|
|
@ -318,7 +399,9 @@
|
|||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="usedstep.remark" placeholder="输入备注信息" />
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<div style="text-align: right">
|
||||
|
|
@ -327,10 +410,7 @@
|
|||
</div>
|
||||
</el-dialog>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="检验要求">
|
||||
<el-button type="primary" icon="el-icon-plus"
|
||||
>新增</el-button>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="技术文件">
|
||||
<el-button type="primary" icon="el-icon-plus" @click="handletechdocCreate"
|
||||
>新增</el-button>
|
||||
|
|
@ -426,7 +506,8 @@
|
|||
<script>
|
||||
import { getMaterialList,getMaterial,getInputmaterialList,createInputmaterial,updateInputmaterial
|
||||
,deleteInputmaterial,getOutputmaterialList,createOutputmaterial,updateOutputmaterial,deleteOutputmaterial,
|
||||
getUsedstepList,createUsedstep,deleteUsedstep,getStepList,gettechdocList,createtechdoc,updatetechdoc,deletetechdoc } from "@/api/mtm";
|
||||
getUsedstepList,createUsedstep,deleteUsedstep,getStepList,gettechdocList,createtechdoc,updatetechdoc,deletetechdoc
|
||||
,getsubproducationList,createsubproducation,updatesubproducation,deletesubproducation } from "@/api/mtm";
|
||||
import { quillEditor } from 'vue-quill-editor'
|
||||
import 'quill/dist/quill.core.css'
|
||||
import 'quill/dist/quill.snow.css'
|
||||
|
|
@ -446,6 +527,9 @@ const defaultusedstep = {
|
|||
};
|
||||
const defaulttechdoc = {
|
||||
|
||||
};
|
||||
const defaultsubproducation = {
|
||||
|
||||
};
|
||||
|
||||
export default {
|
||||
|
|
@ -454,9 +538,11 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
materialoptions:[],
|
||||
subproducationData:"",
|
||||
inputtableData:"",
|
||||
editorOption: {} ,
|
||||
techdoc: defaulttechdoc,
|
||||
subproducation:defaultsubproducation,
|
||||
inputmaterial: defaultinputmaterial,
|
||||
techdoctableData:"",
|
||||
outputtableData:"",
|
||||
|
|
@ -475,6 +561,9 @@ export default {
|
|||
page: 1,
|
||||
page_size: 20,
|
||||
},
|
||||
listQuerysubproducation: {
|
||||
page: 0,
|
||||
},
|
||||
listQueryinput: {
|
||||
page: 0,
|
||||
},
|
||||
|
|
@ -487,10 +576,15 @@ export default {
|
|||
listQuerytechdoc:{
|
||||
page: 0,
|
||||
},
|
||||
listQuerystep:{
|
||||
page: 0,
|
||||
},
|
||||
values:7,
|
||||
products:"",
|
||||
dialogType: "new",
|
||||
dialogVisible:false,
|
||||
dialogTypesp: "new",
|
||||
dialogVisiblesp:false,
|
||||
dialogType1: "new",
|
||||
dialogVisible1:false,
|
||||
dialogTypeusedstep: "new",
|
||||
|
|
@ -545,8 +639,19 @@ export default {
|
|||
handleCurrentChange(row){
|
||||
this.product=row.id;
|
||||
this.getMaterial();
|
||||
this.getsubproducationList();
|
||||
},
|
||||
//点击产品分解弹出输入、输出物料,子工序,技术文件
|
||||
handlespChange(row){
|
||||
this.subproduction = row.id;
|
||||
this.getmaterialList();//物料列表
|
||||
this.getInputmaterialLists();//输入物料
|
||||
|
||||
this.getOutputmaterialLists();//输出物料
|
||||
this.getstepList();//子工序
|
||||
this. getUsedstepLists();//
|
||||
this.gettechdocLists();//技术文件
|
||||
},
|
||||
//工艺点击信息
|
||||
|
||||
stepclick(id)
|
||||
|
|
@ -563,15 +668,84 @@ export default {
|
|||
|
||||
},
|
||||
|
||||
//产品分解
|
||||
getsubproducationList(){
|
||||
|
||||
this.listQuerysubproducation.product=this.product
|
||||
getsubproducationList(this.listQuerysubproducation).then((response) => {
|
||||
if (response.data) {
|
||||
|
||||
this.subproducationData = response.data;//产品信息
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
handlesubproducationCreate()
|
||||
{
|
||||
this.subproducation = Object.assign({}, defaultsubproducation);
|
||||
this.dialogTypesp = "new";
|
||||
this.dialogVisiblesp = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs["Formsp"].clearValidate();
|
||||
});
|
||||
},
|
||||
handlesubproducationEdit(scope) {
|
||||
this.subproducation = Object.assign({}, scope.row); // copy obj
|
||||
this.dialogTypesp = "edit";
|
||||
this.dialogVisiblesp = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs["Formsp"].clearValidate();
|
||||
});
|
||||
},
|
||||
handlesubproducationDelete(scope) {
|
||||
this.$confirm("确认删除?", "警告", {
|
||||
confirmButtonText: "确认",
|
||||
cancelButtonText: "取消",
|
||||
type: "error",
|
||||
})
|
||||
.then(async () => {
|
||||
await deletesubproducation(scope.row.id);
|
||||
this.getsubproducationList()
|
||||
this.$message.success("成功");
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
},
|
||||
async subproducationfirm(form) {
|
||||
this.$refs[form].validate((valid) => {
|
||||
if (valid) {
|
||||
const isEdit = this.dialogTypesp === "edit";
|
||||
if (isEdit) {
|
||||
this.subproducation.product=this.product;
|
||||
updatesubproducation(this.subproducation.id, this.subproducation).then((res) => {
|
||||
if (res.code >= 200) {
|
||||
this.getsubproducationList()
|
||||
this.dialogVisiblesp = false;
|
||||
this.$message.success("成功");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.subproducation.product=this.product;
|
||||
createsubproducation(this.subproducation).then((res) => {
|
||||
if (res.code >= 200) {
|
||||
this.getsubproducationList()
|
||||
this.dialogVisiblesp = false;
|
||||
this.$message.success("成功");
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
//输入物料列表
|
||||
|
||||
getInputmaterialLists(){
|
||||
|
||||
this.listQueryinput.process=this.process;
|
||||
this.listQueryinput.product=this.product
|
||||
this.listQueryinput.subproduction=this.subproduction;
|
||||
getInputmaterialList(this.listQueryinput).then((response) => {
|
||||
if (response.data) {
|
||||
|
||||
|
|
@ -617,8 +791,7 @@ export default {
|
|||
if (valid) {
|
||||
const isEdit = this.dialogType === "edit";
|
||||
if (isEdit) {
|
||||
this.inputmaterial.process=this.process;
|
||||
this.inputmaterial.product=this.product;
|
||||
this.inputmaterial.subproduction=this.subproduction;
|
||||
updateInputmaterial(this.inputmaterial.id, this.inputmaterial).then((res) => {
|
||||
if (res.code >= 200) {
|
||||
this.getInputmaterialLists()
|
||||
|
|
@ -627,8 +800,7 @@ export default {
|
|||
}
|
||||
});
|
||||
} else {
|
||||
this.inputmaterial.process=this.process;
|
||||
this.inputmaterial.product=this.product;
|
||||
this.inputmaterial.subproduction=this.subproduction;
|
||||
createInputmaterial(this.inputmaterial).then((res) => {
|
||||
if (res.code >= 200) {
|
||||
this.getInputmaterialLists()
|
||||
|
|
@ -650,8 +822,7 @@ export default {
|
|||
|
||||
getOutputmaterialLists(){
|
||||
|
||||
this.listQueryoutput.process=this.process;
|
||||
this.listQueryoutput.product=this.product
|
||||
this.listQueryoutput.subproduction=this.subproduction;
|
||||
// this.listQueryoutput.page=0;
|
||||
getOutputmaterialList(this.listQueryoutput).then((response) => {
|
||||
if (response.data) {
|
||||
|
|
@ -700,8 +871,7 @@ export default {
|
|||
if (valid) {
|
||||
const isEdit = this.dialogType1 === "edit";
|
||||
if (isEdit) {
|
||||
this.outputmaterial.process=this.process;
|
||||
this.outputmaterial.product=this.product;
|
||||
this.outputmaterial.subproduction=this.subproduction;
|
||||
updateOutputmaterial(this.outputmaterial.id, this.outputmaterial).then((res) => {
|
||||
if (res.code >= 200) {
|
||||
this.getOutputmaterialLists()
|
||||
|
|
@ -710,8 +880,7 @@ export default {
|
|||
}
|
||||
});
|
||||
} else {
|
||||
this.outputmaterial.process=this.process;
|
||||
this.outputmaterial.product=this.product;
|
||||
this.outputmaterial.subproduction=this.subproduction;
|
||||
console.log(this.outputmaterial);
|
||||
createOutputmaterial(this.outputmaterial).then((res) => {
|
||||
if (res.code >= 200) {
|
||||
|
|
@ -730,8 +899,7 @@ export default {
|
|||
|
||||
getUsedstepLists(){
|
||||
|
||||
this.listQueryusedstep.process=this.process;
|
||||
this.listQueryusedstep.product=this.product
|
||||
this.listQueryusedstep.subproduction=this.subproduction;
|
||||
// this.listQueryusedstep.page=0;
|
||||
getUsedstepList(this.listQueryusedstep).then((response) => {
|
||||
if (response.data) {
|
||||
|
|
@ -744,7 +912,7 @@ export default {
|
|||
|
||||
getstepList() {
|
||||
|
||||
getStepList(this.process).then((response) => {
|
||||
getStepList(this.listQuerystep).then((response) => {
|
||||
if (response.data) {
|
||||
this.stepoptions = genTree(response.data);
|
||||
}
|
||||
|
|
@ -794,12 +962,12 @@ export default {
|
|||
},
|
||||
async usedstepconfirm(form) {
|
||||
|
||||
this.usedstep.process=this.process;
|
||||
this.usedstep.product=this.product;
|
||||
this.usedstep.subproduction=this.subproduction;
|
||||
console.log(this.usedstep);
|
||||
createUsedstep(this.usedstep).then((res) => {
|
||||
if (res.code >= 200) {
|
||||
this.getUsedstepLists()
|
||||
this.getUsedstepLists();
|
||||
this.getMaterial();
|
||||
this.dialogVisibleusedstep = false;
|
||||
this.$message.success("成功");
|
||||
}
|
||||
|
|
@ -807,8 +975,7 @@ export default {
|
|||
},
|
||||
//技术文件
|
||||
gettechdocLists(){
|
||||
this.listQuerytechdoc.process=this.process;
|
||||
this.listQuerytechdoc.product=this.product;
|
||||
this.listQuerytechdoc.subproduction=this.subproduction;
|
||||
// this.listQuerytechdoc.page=0;
|
||||
gettechdocList(this.listQuerytechdoc).then((response) => {
|
||||
if (response.data) {
|
||||
|
|
@ -887,8 +1054,7 @@ export default {
|
|||
}
|
||||
});
|
||||
} else {
|
||||
this.techdoc.process=this.process;
|
||||
this.techdoc.product=this.product;
|
||||
this.techdoc.subproduction=this.subproduction;
|
||||
createtechdoc(this.techdoc).then((res) => {
|
||||
if (res.code >= 200) {
|
||||
this.gettechdocLists();
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { getStepList, createStep,updateStep,deleteStep } from "@/api/mtm";
|
||||
import { getStepLists, createStep,updateStep,deleteStep } from "@/api/mtm";
|
||||
import checkPermission from "@/utils/permission";
|
||||
import { getEquipmentAll } from "@/api/equipment";
|
||||
import { upUrl, upHeaders } from "@/api/file";
|
||||
|
|
@ -502,7 +502,7 @@
|
|||
//子工序列表
|
||||
getList() {
|
||||
this.listLoading = true;
|
||||
getStepList(this.step.process).then((response) => {
|
||||
getStepLists(this.step.process).then((response) => {
|
||||
if (response.data) {
|
||||
this.stepList = response.data;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,288 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>生产任务列表</span>
|
||||
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
:data="productionplanList.results"
|
||||
border
|
||||
fit
|
||||
stripe
|
||||
style="width: 100%"
|
||||
max-height="400"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
|
||||
|
||||
|
||||
<el-table-column label="生产计划编号">
|
||||
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="生产订单编号">
|
||||
<template slot-scope="scope">{{ scope.row.order_.number }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="合同编号">
|
||||
<template slot-scope="scope">{{ scope.row.order_.contract_.number }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="客户名称">
|
||||
<template slot-scope="scope">{{ scope.row.order_.customer_.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产品信息">
|
||||
<template slot-scope="scope">{{ scope.row.product_.number }}-{{ scope.row.product_.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产品型号">
|
||||
<template slot-scope="scope">{{ scope.row.product_.specification }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产品单位">
|
||||
<template slot-scope="scope">{{ scope.row.product_.unit }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="生产数量">
|
||||
<template slot-scope="scope">{{ scope.row.count }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="计划开工时间">
|
||||
<template slot-scope="scope">{{ scope.row.start_date }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="计划完工时间">
|
||||
<template slot-scope="scope">{{ scope.row.end_date }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="交付截止时间">
|
||||
<template slot-scope="scope">{{ scope.row.order_.delivery_date }}</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="创建时间">
|
||||
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
label="操作"
|
||||
width="100px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
|
||||
<el-link type="primary"
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
@click="handleclick(scope)"
|
||||
>车间排产</el-link
|
||||
>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="productionplanList.count > 0"
|
||||
:total="productionplanList.count"
|
||||
:page.sync="listQuery1.page"
|
||||
:limit.sync="listQuery1.page_size"
|
||||
@pagination="getplanList"
|
||||
/>
|
||||
</el-card>
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="订单排产">
|
||||
|
||||
|
||||
<el-table
|
||||
:data="orderList.results"
|
||||
border
|
||||
fit
|
||||
stripe
|
||||
style="width: 100%"
|
||||
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
|
||||
<el-table-column label="订单编号">
|
||||
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="客户">
|
||||
<template slot-scope="scope">{{ scope.row.customer_.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="所属合同">
|
||||
<template slot-scope="scope">{{ scope.row.contract_.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="所需产品">
|
||||
<template slot-scope="scope">{{ scope.row.product_.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产品型号">
|
||||
<template slot-scope="scope">{{ scope.row.product_.specification }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="所需数量">
|
||||
<template slot-scope="scope">{{ scope.row.count }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="已派数量">
|
||||
<template slot-scope="scope">{{ scope.row.planed_count }}</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="交货日期">
|
||||
<template slot-scope="scope">{{ scope.row.delivery_date }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间">
|
||||
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
label="操作"
|
||||
width="220px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
|
||||
<el-link type="primary"
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
@click="handleclick(scope)"
|
||||
>排产</el-link
|
||||
>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="orderList.count > 0"
|
||||
:total="orderList.count"
|
||||
:page.sync="listQuery.page"
|
||||
:limit.sync="listQuery.page_size"
|
||||
@pagination="getorderList"
|
||||
/>
|
||||
<el-dialog
|
||||
:visible.sync="dialogVisible"
|
||||
:title="'排产计划'"
|
||||
>
|
||||
<el-form
|
||||
ref="Form"
|
||||
:model="orderplan"
|
||||
label-width="120px"
|
||||
label-position="right"
|
||||
:rules="rule1"
|
||||
>
|
||||
<el-form-item label="生产计划编号" prop="number">
|
||||
<el-input v-model="orderplan.number" placeholder="生产计划编号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排产数量" prop="count">
|
||||
<el-input type="number" v-model.number="orderplan.count"/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="计划排产时间" prop="value1">
|
||||
<el-date-picker
|
||||
v-model="value1"
|
||||
type="daterange"
|
||||
|
||||
start-placeholder="计划开始日期"
|
||||
end-placeholder="计划结束日期"
|
||||
format="yyyy 年 MM 月 dd 日"
|
||||
value-format="yyyy-MM-dd"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<div style="text-align: right">
|
||||
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="confirm('Form')">确认</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="甘特图">甘特图</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getordertoplan } from "@/api/sam";
|
||||
import { createProductionplan,getProductionplanList} from "@/api/pm";
|
||||
import { getMaterialList } from "@/api/mtm";
|
||||
import checkPermission from "@/utils/permission";
|
||||
|
||||
|
||||
import { genTree } from "@/utils";
|
||||
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
||||
const defaulteorderplan = {
|
||||
};
|
||||
export default {
|
||||
components: { Pagination },
|
||||
data() {
|
||||
return {
|
||||
|
||||
orderplan: defaulteorderplan,
|
||||
orderList: {
|
||||
count: 0,
|
||||
},
|
||||
listQuery: {
|
||||
page: 1,
|
||||
page_size: 20,
|
||||
},
|
||||
productionplanList: {
|
||||
count: 0,
|
||||
},
|
||||
listQuery1: {
|
||||
page: 1,
|
||||
page_size: 20,
|
||||
},
|
||||
value1: '',
|
||||
listLoading: true,
|
||||
dialogVisible: false,
|
||||
dialogType: "new",
|
||||
rule1: {
|
||||
number: [{ required: true, message: "请输入", trigger: "blur" }],
|
||||
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
created() {
|
||||
|
||||
this.getorderList();
|
||||
this.getplanList();
|
||||
},
|
||||
methods: {
|
||||
checkPermission,
|
||||
//订单列表
|
||||
getorderList() {
|
||||
this.listLoading = true;
|
||||
getordertoplan(this.listQuery).then((response) => {
|
||||
if (response.data) {
|
||||
this.orderList = response.data;
|
||||
}
|
||||
this.listLoading = false;
|
||||
});
|
||||
},
|
||||
//生产计划列表
|
||||
//列表
|
||||
getplanList() {
|
||||
this.listLoading = true;
|
||||
getProductionplanList(this.listQuery).then((response) => {
|
||||
if (response.data) {
|
||||
this.productionplanList = response.data;
|
||||
}
|
||||
this.listLoading = false;
|
||||
});
|
||||
},
|
||||
handleclick(scope){
|
||||
this.orderID = scope.row.id;
|
||||
|
||||
this.dialogVisible = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs["Form"].clearValidate();
|
||||
});
|
||||
|
||||
},
|
||||
async confirm(form) {
|
||||
|
||||
this.orderplan.start_date = this.value1[0];
|
||||
this.orderplan.end_date = this.value1[1];
|
||||
this.orderplan.order = this.orderID
|
||||
createProductionplan(this.orderplan).then((res) => {
|
||||
if (res.code >= 200) {
|
||||
this.getorderList();
|
||||
this.getplanList();
|
||||
this.dialogVisible = false;
|
||||
this.$message.success("成功");
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
</script>
|
||||
|
|
@ -0,0 +1,308 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-card >
|
||||
<div slot="header" class="clearfix">
|
||||
<span>合同订单列表</span>
|
||||
|
||||
</div>
|
||||
<el-table
|
||||
:data="orderList.results"
|
||||
border
|
||||
fit
|
||||
stripe
|
||||
style="width: 100%"
|
||||
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
|
||||
<el-table-column label="订单编号">
|
||||
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="客户">
|
||||
<template slot-scope="scope">{{ scope.row.customer_.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="所属合同">
|
||||
<template slot-scope="scope">{{ scope.row.contract_.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="所需产品">
|
||||
<template slot-scope="scope">{{ scope.row.product_.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产品型号">
|
||||
<template slot-scope="scope">{{ scope.row.product_.specification }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="所需数量">
|
||||
<template slot-scope="scope">{{ scope.row.count }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="已派数量">
|
||||
<template slot-scope="scope">{{ scope.row.planed_count }}</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="交货日期">
|
||||
<template slot-scope="scope">{{ scope.row.delivery_date }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间">
|
||||
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
label="操作"
|
||||
width="120px"
|
||||
fixed="right"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
|
||||
<el-link type="primary"
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
@click="handleclick(scope)"
|
||||
>排产</el-link
|
||||
>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="orderList.count > 0"
|
||||
:total="orderList.count"
|
||||
:page.sync="listQuery.page"
|
||||
:limit.sync="listQuery.page_size"
|
||||
@pagination="getorderList"
|
||||
/>
|
||||
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-card >
|
||||
<div slot="header" class="clearfix">
|
||||
<span>物料配置</span>
|
||||
|
||||
</div>
|
||||
<el-table
|
||||
:data="orderList.results"
|
||||
border
|
||||
fit
|
||||
stripe
|
||||
style="width: 100%"
|
||||
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
|
||||
<el-table-column label="订单编号">
|
||||
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="客户">
|
||||
<template slot-scope="scope">{{ scope.row.customer_.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="所属合同">
|
||||
<template slot-scope="scope">{{ scope.row.contract_.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="所需产品">
|
||||
<template slot-scope="scope">{{ scope.row.product_.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产品型号">
|
||||
<template slot-scope="scope">{{ scope.row.product_.specification }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="所需数量">
|
||||
<template slot-scope="scope">{{ scope.row.count }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="已派数量">
|
||||
<template slot-scope="scope">{{ scope.row.planed_count }}</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="交货日期">
|
||||
<template slot-scope="scope">{{ scope.row.delivery_date }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间">
|
||||
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
label="操作"
|
||||
width="120px"
|
||||
fixed="right"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
|
||||
<el-link type="primary"
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
@click="handleclick(scope)"
|
||||
>排产</el-link
|
||||
>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="orderList.count > 0"
|
||||
:total="orderList.count"
|
||||
:page.sync="listQuery.page"
|
||||
:limit.sync="listQuery.page_size"
|
||||
@pagination="getorderList"
|
||||
/>
|
||||
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-card >
|
||||
<div slot="header" class="clearfix">
|
||||
<span>设备配置</span>
|
||||
|
||||
</div>
|
||||
<el-table
|
||||
:data="orderList.results"
|
||||
border
|
||||
fit
|
||||
stripe
|
||||
style="width: 100%"
|
||||
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
|
||||
<el-table-column label="订单编号">
|
||||
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="客户">
|
||||
<template slot-scope="scope">{{ scope.row.customer_.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="所属合同">
|
||||
<template slot-scope="scope">{{ scope.row.contract_.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="所需产品">
|
||||
<template slot-scope="scope">{{ scope.row.product_.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产品型号">
|
||||
<template slot-scope="scope">{{ scope.row.product_.specification }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="所需数量">
|
||||
<template slot-scope="scope">{{ scope.row.count }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="已派数量">
|
||||
<template slot-scope="scope">{{ scope.row.planed_count }}</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="交货日期">
|
||||
<template slot-scope="scope">{{ scope.row.delivery_date }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间">
|
||||
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
label="操作"
|
||||
width="120px"
|
||||
fixed="right"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
|
||||
<el-link type="primary"
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
@click="handleclick(scope)"
|
||||
>排产</el-link
|
||||
>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="orderList.count > 0"
|
||||
:total="orderList.count"
|
||||
:page.sync="listQuery.page"
|
||||
:limit.sync="listQuery.page_size"
|
||||
@pagination="getorderList"
|
||||
/>
|
||||
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getordertoplan } from "@/api/sam";
|
||||
import { createProductionplan,getProductionplanList} from "@/api/pm";
|
||||
import { getMaterialList } from "@/api/mtm";
|
||||
import checkPermission from "@/utils/permission";
|
||||
|
||||
|
||||
import { genTree } from "@/utils";
|
||||
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
||||
const defaulteorderplan = {
|
||||
};
|
||||
export default {
|
||||
components: { Pagination },
|
||||
data() {
|
||||
return {
|
||||
|
||||
orderplan: defaulteorderplan,
|
||||
orderList: {
|
||||
count: 0,
|
||||
},
|
||||
listQuery: {
|
||||
page: 1,
|
||||
page_size: 20,
|
||||
},
|
||||
|
||||
|
||||
listLoading: true,
|
||||
dialogVisible: false,
|
||||
dialogType: "new",
|
||||
rule1: {
|
||||
number: [{ required: true, message: "请输入", trigger: "blur" }],
|
||||
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
created() {
|
||||
|
||||
this.getorderList();
|
||||
|
||||
},
|
||||
methods: {
|
||||
checkPermission,
|
||||
//订单列表
|
||||
getorderList() {
|
||||
this.listLoading = true;
|
||||
getordertoplan(this.listQuery).then((response) => {
|
||||
if (response.data) {
|
||||
this.orderList = response.data;
|
||||
}
|
||||
this.listLoading = false;
|
||||
});
|
||||
},
|
||||
|
||||
handleclick(scope){
|
||||
this.orderID = scope.row.id;
|
||||
|
||||
this.dialogVisible = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs["Form"].clearValidate();
|
||||
});
|
||||
|
||||
},
|
||||
async confirm(form) {
|
||||
|
||||
this.orderplan.start_date = this.value1[0];
|
||||
this.orderplan.end_date = this.value1[1];
|
||||
this.orderplan.order = this.orderID
|
||||
createProductionplan(this.orderplan).then((res) => {
|
||||
if (res.code >= 200) {
|
||||
this.getorderList();
|
||||
this.getplanList();
|
||||
this.dialogVisible = false;
|
||||
this.$message.success("成功");
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
</script>
|
||||
|
|
@ -94,24 +94,6 @@ class Migration(migrations.Migration):
|
|||
'verbose_name_plural': '操作记录条目',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ProductProcess',
|
||||
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='删除标记')),
|
||||
('sort', models.IntegerField(default=1, verbose_name='排序号')),
|
||||
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='productprocess_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||
('process', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.process', verbose_name='工序')),
|
||||
('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='产品')),
|
||||
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='productprocess_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '产品生产工序',
|
||||
'verbose_name_plural': '产品生产工序',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='OutputMaterial',
|
||||
fields=[
|
||||
|
|
|
|||
|
|
@ -0,0 +1,137 @@
|
|||
# Generated by Django 3.2.6 on 2021-10-12 01:01
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mtm', '0018_material_count'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='SubProduction',
|
||||
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='删除标记')),
|
||||
('name', models.CharField(blank=True, max_length=50, null=True, verbose_name='命名')),
|
||||
('sort', models.IntegerField(default=1, verbose_name='排序号')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '产品生产工序',
|
||||
'verbose_name_plural': '产品生产工序',
|
||||
},
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='inputmaterial',
|
||||
name='create_by',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='inputmaterial',
|
||||
name='process',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='inputmaterial',
|
||||
name='product',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='inputmaterial',
|
||||
name='update_by',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='material',
|
||||
name='processes',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='outputmaterial',
|
||||
name='create_by',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='outputmaterial',
|
||||
name='process',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='outputmaterial',
|
||||
name='product',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='outputmaterial',
|
||||
name='update_by',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='techdoc',
|
||||
name='create_by',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='techdoc',
|
||||
name='process',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='techdoc',
|
||||
name='product',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='techdoc',
|
||||
name='update_by',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='usedstep',
|
||||
name='create_by',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='usedstep',
|
||||
name='process',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='usedstep',
|
||||
name='product',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='usedstep',
|
||||
name='update_by',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='usedstep',
|
||||
name='remark',
|
||||
field=models.TextField(blank=True, null=True, verbose_name='生产备注'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='step',
|
||||
name='process',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='step_process', to='mtm.process', verbose_name='所属工序'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='subproduction',
|
||||
name='product',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='产品'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='inputmaterial',
|
||||
name='subproduction',
|
||||
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mtm.subproduction', verbose_name='关联生产分解'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='outputmaterial',
|
||||
name='subproduction',
|
||||
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mtm.subproduction', verbose_name='关联生产分解'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='techdoc',
|
||||
name='subproduction',
|
||||
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mtm.subproduction', verbose_name='关联生产分解'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='usedstep',
|
||||
name='subproduction',
|
||||
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mtm.subproduction', verbose_name='关联生产分解'),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
# Generated by Django 3.2.6 on 2021-10-12 08:57
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('mtm', '0019_auto_20211012_0901'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='subproduction',
|
||||
name='create_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subproduction_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='subproduction',
|
||||
name='update_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subproduction_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'),
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
# Generated by Django 3.2.6 on 2021-10-13 00:56
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('mtm', '0020_auto_20211012_1657'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='inputmaterial',
|
||||
name='create_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='inputmaterial_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='inputmaterial',
|
||||
name='update_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='inputmaterial_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='outputmaterial',
|
||||
name='create_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='outputmaterial_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='outputmaterial',
|
||||
name='update_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='outputmaterial_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='techdoc',
|
||||
name='create_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='techdoc_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='techdoc',
|
||||
name='update_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='techdoc_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='usedstep',
|
||||
name='create_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='usedstep_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='usedstep',
|
||||
name='update_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='usedstep_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'),
|
||||
),
|
||||
]
|
||||
|
|
@ -16,9 +16,9 @@ class Material(CommonAModel):
|
|||
(1, '成品'),
|
||||
(2, '半成品'),
|
||||
(3, '主要原料'),
|
||||
(4,'辅助原料') ,
|
||||
(4, '辅助原料') ,
|
||||
(5, '加工工具'),
|
||||
(6,'辅助工具')
|
||||
(6, '辅助工具')
|
||||
)
|
||||
unit_choices =(
|
||||
('块', '块'),
|
||||
|
|
@ -29,7 +29,6 @@ class Material(CommonAModel):
|
|||
specification = models.CharField('型号', max_length=100, null=True, blank=True)
|
||||
type = models.CharField('物料类型', choices= type_choices, max_length=20, default=1)
|
||||
sort_str = models.CharField('排序字符', max_length=100, null=True, blank=True)
|
||||
processes = models.JSONField('工艺流程', default=list, blank=True, null=True)
|
||||
unit = models.CharField('基准计量单位', choices=unit_choices, default='块', max_length=10)
|
||||
count = models.IntegerField('物料总数', default=0)
|
||||
class Meta:
|
||||
|
|
@ -60,7 +59,7 @@ class Step(CommonAModel):
|
|||
"""
|
||||
工序步骤
|
||||
"""
|
||||
process = models.ForeignKey(Process, on_delete=models.CASCADE, verbose_name='所属工序')
|
||||
process = models.ForeignKey(Process, on_delete=models.CASCADE, verbose_name='所属工序', related_name='step_process')
|
||||
name = models.CharField('工序步骤名称', max_length=100)
|
||||
number = models.CharField('步骤编号', max_length=100, null=True, blank=True)
|
||||
instruction_content = models.TextField('相应操作指导', null=True, blank=True)
|
||||
|
|
@ -127,26 +126,28 @@ class RecordFormField(CommonAModel):
|
|||
def __str__(self):
|
||||
return self.field_key + '-' + self.field_name
|
||||
|
||||
class ProductProcess(CommonAModel):
|
||||
|
||||
|
||||
class SubProduction(CommonAModel):
|
||||
"""
|
||||
产品生产工艺集
|
||||
产品生产分解
|
||||
"""
|
||||
name = models.CharField('命名', max_length=50, null=True, blank=True)
|
||||
product = models.ForeignKey(Material, verbose_name='产品', on_delete=models.CASCADE)
|
||||
process = models.ForeignKey(Process, verbose_name='工序', on_delete=models.CASCADE)
|
||||
sort = models.IntegerField('排序号', default=1)
|
||||
|
||||
class Meta:
|
||||
verbose_name = '产品生产工序'
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
|
||||
class InputMaterial(CommonAModel):
|
||||
"""
|
||||
输入物料
|
||||
"""
|
||||
material = models.ForeignKey(Material, verbose_name='输入物料', on_delete=models.CASCADE, related_name='inputmaterial')
|
||||
count = models.FloatField('消耗量', default=1)
|
||||
product = models.ForeignKey(Material, verbose_name='关联产品', on_delete=models.CASCADE, related_name='inputmaterial_product')
|
||||
process = models.ForeignKey(Process, verbose_name='关联工序', on_delete=models.CASCADE)
|
||||
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE)
|
||||
sort = models.IntegerField('排序号', default=1)
|
||||
|
||||
class Meta:
|
||||
|
|
@ -161,8 +162,7 @@ class OutputMaterial(CommonAModel):
|
|||
"""
|
||||
material = models.ForeignKey(Material, verbose_name='输出物料', on_delete=models.CASCADE, related_name='outputmaterial')
|
||||
count = models.FloatField('产出量', default=1)
|
||||
product = models.ForeignKey(Material, verbose_name='关联产品', on_delete=models.CASCADE, related_name='outputmaterial_product')
|
||||
process = models.ForeignKey(Process, verbose_name='关联工序', on_delete=models.CASCADE)
|
||||
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE)
|
||||
sort = models.IntegerField('排序号', default=1)
|
||||
|
||||
class Meta:
|
||||
|
|
@ -171,11 +171,11 @@ class OutputMaterial(CommonAModel):
|
|||
|
||||
class UsedStep(CommonAModel):
|
||||
"""
|
||||
产品生产子工序
|
||||
涉及的生产子工序
|
||||
"""
|
||||
step = models.ForeignKey(Step, verbose_name='子工序', on_delete=models.CASCADE, related_name='usedsteps')
|
||||
product = models.ForeignKey(Material, verbose_name='关联产品', on_delete=models.CASCADE)
|
||||
process = models.ForeignKey(Process, verbose_name='关联工序', on_delete=models.CASCADE)
|
||||
remark = models.TextField('生产备注', null=True, blank=True)
|
||||
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE)
|
||||
|
||||
class Meta:
|
||||
verbose_name = '产品生产子工序'
|
||||
|
|
@ -188,8 +188,7 @@ class TechDoc(CommonAModel):
|
|||
"""
|
||||
name = models.CharField('名称', max_length=50)
|
||||
file = models.ForeignKey(File, verbose_name='技术文件', on_delete=models.CASCADE)
|
||||
product = models.ForeignKey(Material, verbose_name='关联产品', on_delete=models.CASCADE)
|
||||
process = models.ForeignKey(Process, verbose_name='关联工序', on_delete=models.CASCADE)
|
||||
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE)
|
||||
content = models.TextField('内容', null=True, blank=True)
|
||||
|
||||
class Meta:
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
from apps.em.serializers import EquipmentSimpleSerializer
|
||||
from rest_framework import serializers
|
||||
from rest_framework.exceptions import ParseError, ValidationError
|
||||
from .models import InputMaterial, Material, OutputMaterial, Process, ProductProcess, RecordForm, RecordFormField, Step, TechDoc, UsedStep
|
||||
from .models import InputMaterial, Material, OutputMaterial, Process, RecordForm, RecordFormField, Step, TechDoc, UsedStep, SubProduction
|
||||
from apps.system.serializers import FileSimpleSerializer, OrganizationSimpleSerializer
|
||||
|
||||
|
||||
class MaterialSerializer(serializers.ModelSerializer):
|
||||
processes = serializers.ListField(child=serializers.IntegerField(min_value=1))
|
||||
class Meta:
|
||||
model = Material
|
||||
fields = '__all__'
|
||||
|
|
@ -18,7 +17,8 @@ class MaterialDetailSerializer(serializers.ModelSerializer):
|
|||
fields = '__all__'
|
||||
|
||||
def get_processes_(self, obj):
|
||||
objs = Process.objects.filter(id__in=obj.processes).order_by('number')
|
||||
steps = UsedStep.objects.filter(subproduction__product=obj).values_list('step', flat=True)
|
||||
objs = Process.objects.filter(step_process__id__in=steps).distinct().order_by('number')
|
||||
return ProcessSimpleSerializer(instance=objs, many=True).data
|
||||
|
||||
|
||||
|
|
@ -60,18 +60,11 @@ class StepDetailSerializer(serializers.ModelSerializer):
|
|||
queryset = queryset.prefetch_related('equipments')
|
||||
return queryset
|
||||
|
||||
class ProductProcessListSerializer(serializers.ModelSerializer):
|
||||
process_ = ProcessSimpleSerializer(source='process', read_only=True)
|
||||
product_ = MaterialSimpleSerializer(source='product', read_only=True)
|
||||
class SubProductionSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = ProductProcess
|
||||
model = SubProduction
|
||||
fields = '__all__'
|
||||
|
||||
class ProductProcessUpdateSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = ProductProcess
|
||||
fields = ['sort']
|
||||
|
||||
class InputMaterialListSerializer(serializers.ModelSerializer):
|
||||
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
||||
class Meta:
|
||||
|
|
@ -88,10 +81,10 @@ class OutputMaterialListSerializer(serializers.ModelSerializer):
|
|||
class InputMaterialSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = InputMaterial
|
||||
fields = ['count', 'sort', 'material', 'product', 'process']
|
||||
fields = ['count', 'sort', 'material', 'subproduction']
|
||||
|
||||
def create(self, validated_data):
|
||||
if InputMaterial.objects.filter(material=validated_data['material'], product=validated_data['product'], process=validated_data['process'], is_deleted=False).exists():
|
||||
if InputMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False).exists():
|
||||
raise ValidationError('该物料已存在')
|
||||
return super().create(validated_data)
|
||||
|
||||
|
|
@ -103,10 +96,10 @@ class InputMaterialUpdateSerializer(serializers.ModelSerializer):
|
|||
class OutputMaterialSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = OutputMaterial
|
||||
fields = ['count', 'sort', 'material', 'product', 'process']
|
||||
fields = ['count', 'sort', 'material', 'subproduction']
|
||||
|
||||
def create(self, validated_data):
|
||||
if OutputMaterial.objects.filter(material=validated_data['material'], product=validated_data['product'], process=validated_data['process'], is_deleted=False).exists():
|
||||
if OutputMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False).exists():
|
||||
raise ValidationError('该物料已存在')
|
||||
return super().create(validated_data)
|
||||
|
||||
|
|
@ -121,7 +114,15 @@ class UsedStepCreateSerializer(serializers.ModelSerializer):
|
|||
"""
|
||||
class Meta:
|
||||
model = UsedStep
|
||||
fields = ['step', 'product', 'process']
|
||||
fields = ['step', 'subproduction', 'remark']
|
||||
|
||||
class UsedStepUpdateSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
产品生产子工序编辑
|
||||
"""
|
||||
class Meta:
|
||||
model = UsedStep
|
||||
fields = ['remark']
|
||||
|
||||
class UsedStepListSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
|
|
@ -198,7 +199,7 @@ class TechDocListSerializer(serializers.ModelSerializer):
|
|||
class TechDocCreateSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = TechDoc
|
||||
fields = ['file', 'product', 'process', 'name', 'content']
|
||||
fields = ['file', 'subproduction', 'name', 'content']
|
||||
|
||||
class TechDocUpdateSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
from django.db.models import base
|
||||
from rest_framework import urlpatterns
|
||||
from apps.mtm.views import InputMaterialViewSet, MaterialViewSet, OutputMaterialViewSet, ProcessViewSet, RecordFormFieldViewSet, RecordFormViewSet, StepViewSet, TechDocViewSet, UsedStepViewSet
|
||||
from apps.mtm.views import InputMaterialViewSet, MaterialViewSet, OutputMaterialViewSet, ProcessViewSet, RecordFormFieldViewSet, RecordFormViewSet, StepViewSet, SubProductionViewSet, TechDocViewSet, UsedStepViewSet
|
||||
from django.urls import path, include
|
||||
from rest_framework.routers import DefaultRouter
|
||||
|
||||
router = DefaultRouter()
|
||||
router.register('material', MaterialViewSet, basename='material')
|
||||
router.register('process', ProcessViewSet, basename='process')
|
||||
# router.register('productprocess', ProductProcessViewSet, basename='productprocess')
|
||||
router.register('step', StepViewSet, basename='step')
|
||||
router.register('subproducation', SubProductionViewSet, basename='subproducation')
|
||||
router.register('inputmaterial', InputMaterialViewSet, basename='inputmaterial')
|
||||
router.register('outputmaterial', OutputMaterialViewSet, basename='outputmaterial')
|
||||
router.register('usedstep', UsedStepViewSet, basename='usedstep')
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ from django.shortcuts import render
|
|||
from rest_framework.viewsets import ModelViewSet, GenericViewSet
|
||||
from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin
|
||||
|
||||
from apps.mtm.models import InputMaterial, Material, OutputMaterial, Process, ProductProcess, RecordForm, RecordFormField, Step, TechDoc, UsedStep
|
||||
from apps.mtm.serializers import InputMaterialListSerializer, InputMaterialSerializer, InputMaterialUpdateSerializer, MaterialDetailSerializer, MaterialSerializer, MaterialSimpleSerializer, OutputMaterialListSerializer, OutputMaterialSerializer, OutputMaterialUpdateSerializer, ProductProcessListSerializer, ProductProcessUpdateSerializer, ProcessSerializer, RecordFormCreateSerializer, RecordFormFieldCreateSerializer, RecordFormFieldSerializer, RecordFormFieldUpdateSerializer, RecordFormSerializer, RecordFormUpdateSerializer, StepDetailSerializer, StepSerializer, TechDocCreateSerializer, TechDocListSerializer, TechDocUpdateSerializer, UsedStepCreateSerializer, UsedStepListSerializer
|
||||
from apps.mtm.models import InputMaterial, Material, OutputMaterial, Process, RecordForm, RecordFormField, Step, TechDoc, UsedStep, SubProduction
|
||||
from apps.mtm.serializers import InputMaterialListSerializer, InputMaterialSerializer, InputMaterialUpdateSerializer, MaterialDetailSerializer, MaterialSerializer, MaterialSimpleSerializer, OutputMaterialListSerializer, OutputMaterialSerializer, OutputMaterialUpdateSerializer, ProcessSerializer, RecordFormCreateSerializer, RecordFormFieldCreateSerializer, RecordFormFieldSerializer, RecordFormFieldUpdateSerializer, RecordFormSerializer, RecordFormUpdateSerializer, StepDetailSerializer, StepSerializer, SubProductionSerializer, TechDocCreateSerializer, TechDocListSerializer, TechDocUpdateSerializer, UsedStepCreateSerializer, UsedStepListSerializer, UsedStepUpdateSerializer
|
||||
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
|
|
@ -30,15 +30,6 @@ class MaterialViewSet(PageOrNot, CreateUpdateModelAMixin, ModelViewSet):
|
|||
return MaterialDetailSerializer
|
||||
return MaterialSerializer
|
||||
|
||||
# @action(methods=['get'], detail=True, perms_map={'get':'*'}, pagination_class=None, serializer_class=MaterialSimpleSerializer)
|
||||
# def processes(self, request, pk=None):
|
||||
# """
|
||||
# 产品生产工艺流程
|
||||
# """
|
||||
# material = self.get_object()
|
||||
# serializer = self.serializer_class(instance=Process.objects.filter(id__in=material.processes), many=True)
|
||||
# return Response(serializer.data)
|
||||
|
||||
|
||||
class ProcessViewSet(PageOrNot, CreateUpdateModelAMixin, ModelViewSet):
|
||||
"""
|
||||
|
|
@ -62,11 +53,11 @@ class ProcessViewSet(PageOrNot, CreateUpdateModelAMixin, ModelViewSet):
|
|||
serializer = self.serializer_class(instance=Step.objects.prefetch_related('equipments').filter(process=process, is_deleted=False), many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
class StepViewSet(OptimizationMixin, CreateUpdateModelAMixin, CreateModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin, GenericViewSet):
|
||||
class StepViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet):
|
||||
"""
|
||||
子工序-增删改查
|
||||
"""
|
||||
perms_map = {'*':'process_update'}
|
||||
perms_map = {'*':'*'}
|
||||
queryset = Step.objects.all()
|
||||
serializer_class = StepSerializer
|
||||
search_fields = ['name', 'number']
|
||||
|
|
@ -78,20 +69,16 @@ class StepViewSet(OptimizationMixin, CreateUpdateModelAMixin, CreateModelMixin,
|
|||
return StepDetailSerializer
|
||||
return StepSerializer
|
||||
|
||||
# class ProductProcessViewSet(PageOrNot, CreateModelMixin, UpdateModelMixin, ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||
# """
|
||||
# 产品生产工艺流程增删改查
|
||||
# """
|
||||
# perms_map={'*':'*'}
|
||||
# queryset = ProductProcess.objects.select_related('process', 'product').all()
|
||||
# filterset_fields = ['process', 'product']
|
||||
# serializer_class = ProductProcessListSerializer
|
||||
# ordering = ['sort']
|
||||
|
||||
# def get_serializer_class(self):
|
||||
# if self.action == 'update':
|
||||
# return ProductProcessUpdateSerializer
|
||||
# return super().get_serializer_class()
|
||||
class SubProductionViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
||||
"""
|
||||
产品生产分解增删改查
|
||||
"""
|
||||
perms_map={'*':'*'}
|
||||
queryset = SubProduction.objects.all()
|
||||
filterset_fields = ['product']
|
||||
search_fields = ['name']
|
||||
serializer_class = SubProductionSerializer
|
||||
ordering = ['sort']
|
||||
|
||||
class InputMaterialViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
||||
"""
|
||||
|
|
@ -100,7 +87,7 @@ class InputMaterialViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
|||
perms_map = {'*':'*'}
|
||||
queryset = InputMaterial.objects.select_related('material').all()
|
||||
serializer_class = InputMaterialSerializer
|
||||
filterset_fields = ['process', 'product']
|
||||
filterset_fields = ['subproduction']
|
||||
ordering = ['sort', '-create_time']
|
||||
|
||||
def get_serializer_class(self):
|
||||
|
|
@ -117,7 +104,7 @@ class OutputMaterialViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
|||
perms_map = {'*':'*'}
|
||||
queryset = OutputMaterial.objects.select_related('material').all()
|
||||
serializer_class = OutputMaterialSerializer
|
||||
filterset_fields = ['process', 'product']
|
||||
filterset_fields = ['subproduction']
|
||||
ordering = ['sort', '-create_time']
|
||||
|
||||
def get_serializer_class(self):
|
||||
|
|
@ -127,18 +114,20 @@ class OutputMaterialViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
|||
return OutputMaterialUpdateSerializer
|
||||
return OutputMaterialSerializer
|
||||
|
||||
class UsedStepViewSet(OptimizationMixin, CreateUpdateModelAMixin, CreateModelMixin, DestroyModelMixin, ListModelMixin, GenericViewSet):
|
||||
class UsedStepViewSet(OptimizationMixin, CreateModelMixin, DestroyModelMixin, ListModelMixin, UpdateModelMixin, GenericViewSet):
|
||||
"""
|
||||
产品生产子工序表
|
||||
"""
|
||||
perms_map = {'*':'*'}
|
||||
queryset = UsedStep.objects.all()
|
||||
filterset_fields = ['process', 'product', 'step']
|
||||
filterset_fields = ['subproduction', 'step']
|
||||
ordering = ['step__sort', '-step__create_time']
|
||||
|
||||
def get_serializer_class(self):
|
||||
if self.action =='create':
|
||||
return UsedStepCreateSerializer
|
||||
elif self.action == 'update':
|
||||
return UsedStepUpdateSerializer
|
||||
return UsedStepListSerializer
|
||||
|
||||
class RecordFormViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet):
|
||||
|
|
@ -189,7 +178,7 @@ class TechDocViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet):
|
|||
"""
|
||||
perms_map = {'*':'*'}
|
||||
queryset = TechDoc.objects.select_related('file').all()
|
||||
filterset_fields = ['process', 'product']
|
||||
filterset_fields = ['subproduction']
|
||||
search_fields = ['name']
|
||||
ordering = ['-id']
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from rest_framework.views import APIView
|
||||
from apps.system.mixins import CreateUpdateModelAMixin
|
||||
from apps.pm.serializers import ProductionPlanCreateFromOrderSerializer, ProductionPlanSerializer
|
||||
from rest_framework.mixins import CreateModelMixin, ListModelMixin
|
||||
|
|
@ -50,3 +51,6 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel
|
|||
instance = serializer.save(create_by=request.user, product=order.product)
|
||||
updateOrderPlanedCount(instance.order)
|
||||
return Response()
|
||||
|
||||
class ResourceCalculate(APIView):
|
||||
pass
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.2.6 on 2021-10-12 08:23
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('wf', '0011_auto_20210930_0954'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='ticketflow',
|
||||
name='intervene_type',
|
||||
field=models.IntegerField(choices=[(0, '正常处理'), (1, '转交'), (2, '加签'), (3, '加签处理完成'), (4, '接单'), (5, '评论'), (6, '删除'), (7, '强制关闭'), (8, '强制修改状态'), (9, 'hook操作'), (10, '撤回')], default=0, help_text='流转类型', verbose_name='干预类型'),
|
||||
),
|
||||
]
|
||||
|
|
@ -39,7 +39,7 @@ class State(CommonAModel):
|
|||
PARTICIPANT_TYPE_ROBOT = 6
|
||||
PARTICIPANT_TYPE_FIELD = 7
|
||||
PARTICIPANT_TYPE_PARENT_FIELD = 8
|
||||
type2_choices = (
|
||||
state_participanttype_choices = (
|
||||
(0, '无处理人'),
|
||||
(PARTICIPANT_TYPE_PERSONAL, '个人'),
|
||||
(PARTICIPANT_TYPE_MULTI, '多人'),
|
||||
|
|
@ -70,7 +70,7 @@ class State(CommonAModel):
|
|||
sort = models.IntegerField('状态顺序', default=0, help_text='用于工单步骤接口时,step上状态的顺序(因为存在网状情况,所以需要人为设定顺序),值越小越靠前')
|
||||
type = models.IntegerField('状态类型', default=0, choices=type_choices, help_text='0.普通类型 1.初始状态(用于新建工单时,获取对应的字段必填及transition信息) 2.结束状态(此状态下的工单不得再处理,即没有对应的transition)')
|
||||
enable_retreat = models.BooleanField('允许撤回', default=False, help_text='开启后允许工单创建人在此状态直接撤回工单到初始状态')
|
||||
participant_type = models.IntegerField('参与者类型', choices=type2_choices, default=1, blank=True, help_text='0.无处理人,1.个人,2.多人,3.部门,4.角色,5.变量(支持工单创建人,创建人的leader),6.脚本,7.工单的字段内容(如表单中的"测试负责人",需要为用户名或者逗号隔开的多个用户名),8.父工单的字段内容。 初始状态请选择类型5,参与人填create_by')
|
||||
participant_type = models.IntegerField('参与者类型', choices=state_participanttype_choices, default=1, blank=True, help_text='0.无处理人,1.个人,2.多人,3.部门,4.角色,5.变量(支持工单创建人,创建人的leader),6.脚本,7.工单的字段内容(如表单中的"测试负责人",需要为用户名或者逗号隔开的多个用户名),8.父工单的字段内容。 初始状态请选择类型5,参与人填create_by')
|
||||
participant = models.JSONField('参与者', default=list, blank=True, help_text='可以为空(无处理人的情况,如结束状态)、userid、userid列表\部门id\角色id\变量(create_by,create_by_tl)\脚本记录的id等,包含子工作流的需要设置处理人为loonrobot')
|
||||
state_fields = models.JSONField('表单字段', default=dict, help_text='json格式字典存储,包括读写属性1:只读,2:必填,3:可选. 示例:{"create_time":1,"title":2, "sn":1}, 内置特殊字段participant_info.participant_name:当前处理人信息(部门名称、角色名称),state.state_name:当前状态的状态名,workflow.workflow_name:工作流名称') # json格式存储,包括读写属性1:只读,2:必填,3:可选,4:不显示, 字典的字典
|
||||
distribute_type = models.IntegerField('分配方式', default=1, choices=state_distribute_choices, help_text='1.主动接单(如果当前处理人实际为多人的时候,需要先接单才能处理) 2.直接处理(即使当前处理人实际为多人,也可以直接处理) 3.随机分配(如果实际为多人,则系统会随机分配给其中一个人) 4.全部处理(要求所有参与人都要处理一遍,才能进入下一步)')
|
||||
|
|
@ -87,6 +87,31 @@ class Transition(CommonAModel):
|
|||
(2, '拒绝'),
|
||||
(3, '其他')
|
||||
)
|
||||
TRANSITION_INTERVENE_TYPE_DELIVER = 1 # 转交操作
|
||||
TRANSITION_INTERVENE_TYPE_ADD_NODE = 2 # 加签操作
|
||||
TRANSITION_INTERVENE_TYPE_ADD_NODE_END = 3 # 加签处理完成
|
||||
TRANSITION_INTERVENE_TYPE_ACCEPT = 4 # 接单操作
|
||||
TRANSITION_INTERVENE_TYPE_COMMENT = 5 # 评论操作
|
||||
TRANSITION_INTERVENE_TYPE_DELETE = 6 # 删除操作
|
||||
TRANSITION_INTERVENE_TYPE_CLOSE = 7 # 强制关闭操作
|
||||
TRANSITION_INTERVENE_TYPE_ALTER_STATE = 8 # 强制修改状态操作
|
||||
TRANSITION_INTERVENE_TYPE_HOOK = 9 # hook操作
|
||||
TRANSITION_INTERVENE_TYPE_RETREAT = 10 # 撤回
|
||||
|
||||
intervene_type_choices = (
|
||||
(0, '正常处理'),
|
||||
(TRANSITION_INTERVENE_TYPE_DELIVER, '转交'),
|
||||
(TRANSITION_INTERVENE_TYPE_ADD_NODE, '加签'),
|
||||
(TRANSITION_INTERVENE_TYPE_ADD_NODE_END, '加签处理完成'),
|
||||
(TRANSITION_INTERVENE_TYPE_ACCEPT, '接单'),
|
||||
(TRANSITION_INTERVENE_TYPE_COMMENT, '评论'),
|
||||
(TRANSITION_INTERVENE_TYPE_DELETE, '删除'),
|
||||
(TRANSITION_INTERVENE_TYPE_CLOSE, '强制关闭'),
|
||||
(TRANSITION_INTERVENE_TYPE_ALTER_STATE, '强制修改状态'),
|
||||
(TRANSITION_INTERVENE_TYPE_HOOK, 'hook操作'),
|
||||
(TRANSITION_INTERVENE_TYPE_RETREAT, '撤回')
|
||||
)
|
||||
|
||||
name = models.CharField('操作', max_length=50)
|
||||
workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE, verbose_name='所属工作流')
|
||||
timer = models.IntegerField('定时器(单位秒)', default=0, help_text='单位秒。处于源状态X秒后如果状态都没有过变化则自动流转到目标状态。设置时间有效')
|
||||
|
|
@ -166,7 +191,7 @@ class Ticket(CommonAModel):
|
|||
in_add_node = models.BooleanField('加签状态中', default=False, help_text='是否处于加签状态下')
|
||||
add_node_man = models.ForeignKey(User, verbose_name='加签人', on_delete=models.SET_NULL, null=True, blank=True, help_text='加签操作的人,工单当前处理人处理完成后会回到该处理人,当处于加签状态下才有效')
|
||||
|
||||
participant_type = models.IntegerField('当前处理人类型', default=0, help_text='0.无处理人,1.个人,2.多人', choices=State.type2_choices)
|
||||
participant_type = models.IntegerField('当前处理人类型', default=0, help_text='0.无处理人,1.个人,2.多人', choices=State.state_participanttype_choices)
|
||||
participant = models.JSONField('当前处理人', default=list, blank=True, help_text='可以为空(无处理人的情况,如结束状态)、userid、userid列表')
|
||||
act_state = models.IntegerField('进行状态', default=1, help_text='当前工单的进行状态', choices=act_state_choices)
|
||||
multi_all_person = models.JSONField('全部处理的结果', default=dict, blank=True, help_text='需要当前状态处理人全部处理时实际的处理结果,json格式')
|
||||
|
|
@ -178,7 +203,8 @@ class TicketFlow(BaseModel):
|
|||
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE, verbose_name='关联工单', related_name='ticketflow_ticket')
|
||||
transition = models.ForeignKey(Transition, verbose_name='流转id', help_text='与worklow.Transition关联, 为0时表示认为干预的操作', on_delete=models.CASCADE, null=True, blank=True)
|
||||
suggestion = models.CharField('处理意见', max_length=10000, default='', blank=True)
|
||||
participant_type = models.IntegerField('处理人类型', default=0, help_text='0.无处理人,1.个人,2.多人', choices=State.type2_choices)
|
||||
participant_type = models.IntegerField('处理人类型', default=0, help_text='0.无处理人,1.个人,2.多人', choices=State.state_participanttype_choices)
|
||||
participant = models.ForeignKey(User, verbose_name='处理人', on_delete=models.SET_NULL, null=True, blank=True, related_name='ticketflow_participant')
|
||||
state = models.ForeignKey(State, verbose_name='当前状态', default=0, blank=True, on_delete=models.CASCADE)
|
||||
ticket_data = models.JSONField('工单数据', default=dict, blank=True, help_text='可以用于记录当前表单数据,json格式')
|
||||
intervene_type = models.IntegerField('干预类型', default=0, help_text='流转类型', choices=Transition.intervene_type_choices)
|
||||
|
|
@ -23,7 +23,7 @@ class WorkflowSimpleSerializer(serializers.ModelSerializer):
|
|||
class StateSimpleSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = State
|
||||
fields = ['id', 'name', 'type', 'distribute_type']
|
||||
fields = ['id', 'name', 'type', 'distribute_type', 'enable_retreat']
|
||||
|
||||
class TransitionSerializer(serializers.ModelSerializer):
|
||||
source_state_ = StateSimpleSerializer(source='source_state', read_only=True)
|
||||
|
|
@ -77,7 +77,7 @@ class TicketListSerializer(serializers.ModelSerializer):
|
|||
|
||||
class Meta:
|
||||
model = Ticket
|
||||
fields = ['id', 'title', 'sn', 'workflow', 'workflow_', 'state', 'state_', 'act_state', 'create_time', 'update_time', 'participant_type']
|
||||
fields = ['id', 'title', 'sn', 'workflow', 'workflow_', 'state', 'state_', 'act_state', 'create_time', 'update_time', 'participant_type', 'create_by']
|
||||
|
||||
@staticmethod
|
||||
def setup_eager_loading(queryset):
|
||||
|
|
@ -127,3 +127,6 @@ class TicketHandleSerializer(serializers.Serializer):
|
|||
transition = serializers.IntegerField(label="流转id")
|
||||
ticket_data = serializers.JSONField(label="表单数据json")
|
||||
suggestion = serializers.CharField(label="处理意见", required = False)
|
||||
|
||||
class TicketRetreatSerializer(serializers.Serializer):
|
||||
suggestion = serializers.CharField(label="撤回原因", required = False)
|
||||
|
|
@ -3,7 +3,7 @@ from django.core.exceptions import AppRegistryNotReady
|
|||
from rest_framework.response import Response
|
||||
from rest_framework import serializers
|
||||
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
|
||||
from apps.wf.serializers import CustomFieldSerializer, StateSerializer, TicketCreateSerializer, TicketFlowSerializer, TicketFlowSimpleSerializer, TicketHandleSerializer, TicketSerializer, TransitionSerializer, WorkflowSerializer, TicketListSerializer, TicketDetailSerializer
|
||||
from apps.wf.serializers import CustomFieldSerializer, StateSerializer, TicketCreateSerializer, TicketFlowSerializer, TicketFlowSimpleSerializer, TicketHandleSerializer, TicketRetreatSerializer, TicketSerializer, TransitionSerializer, WorkflowSerializer, TicketListSerializer, TicketDetailSerializer
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||
from rest_framework.decorators import action, api_view
|
||||
|
|
@ -102,6 +102,8 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin
|
|||
return TicketCreateSerializer
|
||||
elif self.action == 'handle':
|
||||
return TicketHandleSerializer
|
||||
elif self.action == 'retreat':
|
||||
return TicketRetreatSerializer
|
||||
elif self.action == 'list':
|
||||
return TicketListSerializer
|
||||
elif self.action == 'retrieve':
|
||||
|
|
@ -281,7 +283,7 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin
|
|||
# 接单日志
|
||||
# 更新工单流转记录
|
||||
TicketFlow.objects.create(ticket=ticket, state=ticket.state, ticket_data=WfService.get_ticket_all_field_value(ticket),
|
||||
suggestion='接单处理', participant_type=State.PARTICIPANT_TYPE_PERSONAL,
|
||||
suggestion='', participant_type=State.PARTICIPANT_TYPE_PERSONAL, intervene_type=Transition.TRANSITION_ATTRIBUTE_TYPE_ACCEPT,
|
||||
participant=request.user, transition=None)
|
||||
return Response()
|
||||
else:
|
||||
|
|
@ -292,7 +294,35 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin
|
|||
"""
|
||||
撤回工单,允许创建人在指定状态撤回工单至初始状态,状态设置中开启允许撤回
|
||||
"""
|
||||
pass
|
||||
ticket = self.get_object()
|
||||
if ticket.create_by != request.user:
|
||||
raise APIException('非创建人不可撤回')
|
||||
if not ticket.state.enable_retreat:
|
||||
raise APIException('该状态不可撤回')
|
||||
start_state = WfService.get_workflow_start_state(ticket.workflow)
|
||||
ticket.state = start_state
|
||||
ticket.participant_type = State.PARTICIPANT_TYPE_PERSONAL
|
||||
ticket.participant = request.user.id
|
||||
ticket.act_state = Ticket.TICKET_ACT_STATE_RETREAT
|
||||
ticket.save()
|
||||
# 更新流转记录
|
||||
suggestion = request.data.get('suggestion', '') # 撤回原因
|
||||
TicketFlow.objects.create(ticket=ticket, state=ticket.state, ticket_data=WfService.get_ticket_all_field_value(ticket),
|
||||
suggestion=suggestion, participant_type=State.PARTICIPANT_TYPE_PERSONAL, intervene_type=Transition.TRANSITION_INTERVENE_TYPE_RETREAT,
|
||||
participant=request.user, transition=None)
|
||||
return Response()
|
||||
|
||||
@action(methods=['post'], detail=True, perms_map={'post':'*'})
|
||||
def add_node(self, request, pk=None):
|
||||
"""
|
||||
加签
|
||||
"""
|
||||
|
||||
def close(self, request, pk=None):
|
||||
"""
|
||||
关闭工单(超级管理员或者创建人在初始状态)
|
||||
"""
|
||||
|
||||
|
||||
class TicketFlowViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Reference in New Issue