<template>
|
<div style="height: 100%">
|
<div class="page-header">
|
<div class="header-left">
|
<a @click="$router.go(-1)"><i class="icon-btn-back"></i></a>
|
<h2>编辑-产品结构</h2>
|
</div>
|
<div class="btn-group header-right">
|
<el-button title="保存" :disabled="isSubmit" v-thinclick="`save`"
|
>保存</el-button
|
>
|
</div>
|
</div>
|
<div class="page-main">
|
<div class="single-structure-basic">
|
<el-form
|
:inline="true"
|
:model="dataForm"
|
:rules="dataRule"
|
ref="dataForm"
|
label-width="80px"
|
class="l-mes"
|
>
|
<el-row>
|
<el-col :span="24">
|
<el-form-item label="零件号" prop="partNo">
|
<el-input
|
v-model="dataForm.partNo"
|
placeholder="请选择零件"
|
@blur="checkPartNo()"
|
>
|
<el-button
|
slot="append"
|
icon="el-icon-search"
|
@click="openPartDialog()"
|
></el-button>
|
</el-input>
|
</el-form-item>
|
<el-form-item label="零件名称" prop="partName">
|
<el-input
|
v-model="dataForm.partName"
|
placeholder="零件名称"
|
:readonly="true"
|
>
|
</el-input>
|
</el-form-item>
|
<el-form-item label="结构类型" prop="bomTypeDb">
|
<el-select
|
v-model="dataForm.bomTypeDb"
|
placeholder="请选择结构类型"
|
style="width:100%"
|
>
|
<el-option
|
v-for="(item, index) in bomTypeDbOptions"
|
:label="item.label"
|
:value="item.value"
|
:key="index"
|
>
|
</el-option>
|
</el-select>
|
</el-form-item>
|
<!-- <el-form-item label="替代" prop="alternativeNo">
|
<el-input v-model="dataForm.alternativeNo"></el-input>
|
</el-form-item>
|
<el-form-item label="替代描述" prop="alternativeDesc">
|
<el-input
|
type="textarea"
|
:autosize="{ minRows: 1, maxRows: 3 }"
|
v-model="dataForm.alternativeDesc"
|
></el-input>
|
</el-form-item> -->
|
<el-form-item label="版本号" prop="version">
|
<el-input v-model="dataForm.version" disabled></el-input>
|
</el-form-item>
|
<el-form-item label="备注" prop="remark">
|
<el-input
|
type="textarea"
|
:autosize="{ minRows: 1, maxRows: 3 }"
|
v-model="dataForm.remark"
|
></el-input>
|
</el-form-item>
|
<!-- <el-form-item label="已同步至IFS" prop="ifsSync">
|
<span
|
style="width: 146px;display: inline-block;font-size:12px;font-weight:bold;"
|
>{{ dataForm.ifsSync ? '是' : '否' }}</span
|
>
|
</el-form-item> -->
|
<el-form-item label="默认结构" prop="master">
|
<el-checkbox v-model="dataForm.master"></el-checkbox>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
</el-form>
|
</div>
|
<div class="single-structure-detail">
|
<el-card class="single-structure-card" shadow="never" style="">
|
<div slot="header" class="clearfix">
|
<div style="float: left; ">
|
<span>子节点</span
|
><span style="color:red;"
|
>(所有子节点保存之后,才可进行拖拽排序!)</span
|
>
|
</div>
|
<div style="float: right; margin-right: 20px">
|
<el-button
|
type="text"
|
size="medium"
|
class="blue-but"
|
@click="addNode()"
|
>添加
|
</el-button>
|
</div>
|
</div>
|
<el-table
|
id="structureComponentTable"
|
ref="nodeTable"
|
:data="nodeList"
|
:default-sort="{ prop: 'lineItemNo' }"
|
height="650"
|
:header-cell-style="{ color: '#999' }"
|
:row-class-name="structureComponentRowClass"
|
>
|
<el-table-column
|
prop="lineItemNo"
|
label="行项号"
|
align="center"
|
width="70"
|
>
|
</el-table-column>
|
<el-table-column
|
label="消耗工序"
|
prop="operationName"
|
align="center"
|
>
|
<template scope="scope">
|
<el-input
|
v-model="scope.row.operationName"
|
placeholder="请选择消耗工序"
|
v-if="scope.row.isUpdate"
|
>
|
<el-button
|
slot="append"
|
icon="el-icon-search"
|
@click="openOperateDialog(scope.row)"
|
></el-button>
|
</el-input>
|
<template v-if="!scope.row.isUpdate">{{
|
scope.row.operationName
|
}}</template>
|
</template>
|
</el-table-column>
|
<el-table-column label="零件号" prop="partNo" align="center">
|
<template scope="scope">
|
<el-input
|
:class="customClass[scope.$index]"
|
v-model="scope.row.partNo"
|
placeholder="请选择零件"
|
v-if="scope.row.isUpdate"
|
@blur="verifyPartNo(scope.row, scope.$index)"
|
@focus="clearClass(scope.$index)"
|
>
|
<el-button
|
slot="append"
|
icon="el-icon-search"
|
@click="openPartDialog(scope.row, scope.$index)"
|
></el-button>
|
</el-input>
|
<template v-if="!scope.row.isUpdate">{{
|
scope.row.partNo
|
}}</template>
|
</template>
|
</el-table-column>
|
<el-table-column
|
label="零件名称"
|
prop="partName"
|
align="center"
|
:show-overflow-tooltip="true"
|
>
|
</el-table-column>
|
<el-table-column label="数量" prop="qpa" align="center">
|
<template slot-scope="scope">
|
<el-input
|
size="small"
|
v-model="scope.row.qpa"
|
placeholder="请填写数量"
|
v-show="scope.row.isUpdate"
|
onkeyup="this.value=this.value.match(/\d+\.?\d{0,8}/);this.dispatchEvent(new Event('input'))"
|
></el-input>
|
<span v-show="!scope.row.isUpdate">{{ scope.row.qpa }}</span>
|
</template>
|
</el-table-column>
|
|
<el-table-column label="单位" prop="unit" align="center">
|
</el-table-column>
|
<!-- <el-table-column label="盘数(盘)" prop="discNum" align="center">
|
<template slot-scope="scope">
|
<el-input
|
size="small"
|
v-model="scope.row.discNum"
|
placeholder="请填写盘数"
|
v-show="scope.row.isUpdate"
|
></el-input>
|
<span v-show="!scope.row.isUpdate">{{
|
scope.row.discNum
|
}}</span>
|
</template>
|
</el-table-column>
|
<el-table-column label="图号" prop="drawingNumber" align="center">
|
</el-table-column> -->
|
<el-table-column align="center" label="操作" width="85px">
|
<template slot-scope="scope">
|
<el-button
|
type="text"
|
size="small"
|
class="blue-but"
|
v-if="!scope.row.isUpdate"
|
@click="editNode(scope.$index, scope.row)"
|
>编辑</el-button
|
>
|
<el-button
|
type="text"
|
size="small"
|
class="blue-but"
|
v-if="scope.row.isUpdate"
|
:loading="nodeSaveLoading"
|
@click="addOrUpdateNode(scope.$index, scope.row)"
|
>保存</el-button
|
>
|
<el-button
|
type="text"
|
size="small"
|
class="red-but"
|
@click="delNode(scope.$index, scope.row)"
|
>删除</el-button
|
>
|
</template>
|
</el-table-column>
|
</el-table>
|
</el-card>
|
</div>
|
</div>
|
<partDialog
|
:currshowlist.sync="showPart"
|
:parentSelectedObj="editNodePart"
|
:parentSelectedIndex="editIndex"
|
@listenToPartEvent="selectPart"
|
/>
|
<operationDialog
|
:currshowlist.sync="showOperate"
|
@listenToOperationEvent="selectOperate"
|
/>
|
</div>
|
</template>
|
<script>
|
import {
|
addObj,
|
putObj,
|
getObj,
|
addComponent,
|
putComponent,
|
delComponent,
|
batchComponent
|
} from '@/api/technology/structure'
|
import { findByNo } from '@/api/basic/part'
|
import partDialog from '@/views/common/part.vue'
|
import operationDialog from '@/views/common/operation.vue'
|
import { remote } from '@/api/admin/dict'
|
export default {
|
components: {
|
partDialog,
|
operationDialog
|
},
|
data() {
|
return {
|
customClass: [],
|
showPart: false,
|
editNodePart: null,
|
editIndex: null,
|
dataForm: {
|
id: null,
|
partNo: null,
|
partId: null,
|
partName: null,
|
remark: null,
|
bomTypeDb: 'M',
|
alternativeNo: '*',
|
alternativeDesc: null,
|
version: null,
|
master: false,
|
ifsSync: false
|
},
|
nodeList: [],
|
dataRule: {
|
partNo: [
|
{ required: true, message: '零件号不能为空', trigger: 'blur' }
|
],
|
version: [
|
{ required: true, message: '版本号不能为空', trigger: 'blur' }
|
],
|
bomTypeDb: [
|
{ required: true, message: '结构类型不能为空', trigger: 'blur' }
|
],
|
alternativeNo: [
|
{ required: true, message: '替代不能为空', trigger: 'blur' }
|
]
|
},
|
showOperate: false,
|
currRow: null,
|
isSubmit: false,
|
nodeSaveLoading: false,
|
bomTypeDbOptions: []
|
}
|
},
|
computed: {
|
editable: function() {
|
if (!this.dataForm.id) {
|
return true
|
}
|
return false
|
}
|
},
|
mounted() {
|
window.addEventListener(
|
'hashchange',
|
() => {
|
const currentPath = window.location.hash.slice(1)
|
if (this.$route.path !== currentPath) {
|
this.$router.push(currentPath)
|
}
|
},
|
false
|
)
|
this.rowDrop()
|
},
|
created() {
|
const formId = this.$route.params.id
|
this.init(formId)
|
this.getBomTypeDbOptions()
|
},
|
methods: {
|
// 查询结构类型字典
|
getBomTypeDbOptions() {
|
remote('bom_type_db').then((response) => {
|
if (response.data.code === 0) {
|
this.bomTypeDbOptions = response.data.data
|
} else {
|
this.bomTypeDbOptions = []
|
}
|
})
|
},
|
init(id) {
|
this.dataForm.id = id || 0
|
this.$nextTick(() => {
|
var formId = this.dataForm.id
|
this.initAllData()
|
if (formId) {
|
getObj(formId).then((response) => {
|
const resCode = response.data.code
|
const resData = response.data.data
|
if (resCode === 0) {
|
this.dataForm.id = resData.id
|
this.dataForm.partNo = resData.partNo
|
this.dataForm.partId = resData.partId
|
this.dataForm.partName = resData.partName
|
this.dataForm.remark = resData.remark
|
this.dataForm.version = resData.version
|
this.dataForm.master = resData.master
|
this.dataForm.bomTypeDb = resData.bomTypeDb
|
this.dataForm.alternativeNo = resData.alternativeNo
|
this.dataForm.alternativeDesc = resData.alternativeDesc
|
this.dataForm.ifsSync = resData.ifsSync
|
const components = resData.components
|
if (components != null && components.length > 0) {
|
let node
|
for (let i = 0; i < components.length; i++) {
|
node = {}
|
node.id = components[i].id
|
node.partId = components[i].partId
|
node.partNo = components[i].partNo
|
node.partName = components[i].partName
|
node.qpa = components[i].qpa
|
node.unit = components[i].unit
|
node.drawingNumber = components[i].drawingNumber
|
node.structureId = components[i].structureId
|
node.operationId = components[i].operationId
|
node.operationNo = components[i].operationNo
|
node.operationName = components[i].operationName
|
node.discNum = components[i].discNum
|
node.lineItemNo = components[i].lineItemNo
|
node.color = components[i].color
|
node.planningMethod = components[i].planningMethod
|
node.isUpdate = false
|
this.nodeList.push(node)
|
}
|
}
|
}
|
})
|
}
|
})
|
},
|
initAllData() {
|
this.dataForm.id = null
|
this.dataForm.partNo = null
|
this.dataForm.partId = null
|
this.dataForm.partName = null
|
this.dataForm.remark = null
|
this.dataForm.version = null
|
this.dataForm.master = false
|
this.dataForm.bomTypeDb = 'M'
|
this.dataForm.alternativeNo = '*'
|
this.dataForm.alternativeDesc = null
|
this.dataForm.ifsSync = false
|
this.showPart = false
|
this.nodeList = []
|
this.showOperate = false
|
this.currRow = null
|
},
|
save() {
|
this.isSubmit = true
|
this.$refs.dataForm.validate((valid) => {
|
if (valid) {
|
if (this.dataForm.id) {
|
putObj(this.dataForm)
|
.then((response) => {
|
var data = response.data
|
if (data.code === 0) {
|
this.$message.success('保存成功')
|
} else {
|
this.$message.error('保存失败')
|
}
|
this.isSubmit = false
|
})
|
.catch(() => {
|
this.isSubmit = false
|
})
|
} else {
|
addObj(this.dataForm)
|
.then((response) => {
|
var data = response.data
|
if (data.code === 0) {
|
this.dataForm.id = data.data
|
this.$message.success('保存成功')
|
} else {
|
this.$message.error('保存失败')
|
}
|
this.isSubmit = false
|
})
|
.catch(() => {
|
this.isSubmit = false
|
})
|
}
|
} else {
|
this.isSubmit = false
|
}
|
})
|
},
|
openPartDialog(nodePart, index) {
|
this.showPart = true
|
this.editNodePart = nodePart
|
this.editIndex = index
|
},
|
openOperateDialog(row) {
|
this.showOperate = true
|
this.currRow = row
|
},
|
selectPart(param, nodePart, index) {
|
if (nodePart) {
|
if (param) {
|
this.$set(nodePart, 'partId', param.id)
|
this.$set(nodePart, 'partName', param.partName)
|
this.$set(nodePart, 'partNo', param.partNo)
|
this.$set(nodePart, 'unit', param.unit)
|
this.$set(nodePart, 'drawingNumber', param.drawingNumber)
|
this.$set(nodePart, 'planningMethod', param.planningMethod)
|
console.info(index)
|
this.clearClass(index)
|
}
|
} else {
|
if (typeof param !== 'undefined') {
|
this.dataForm.partId = param.id
|
this.dataForm.partName = param.partName
|
this.dataForm.partNo = param.partNo
|
this.dataForm.version = param.engChgLevel
|
}
|
}
|
},
|
selectOperate(operate) {
|
const _that = this
|
if (operate) {
|
this.$set(_that.currRow, 'operationId', operate.id)
|
this.$set(_that.currRow, 'operationName', operate.name)
|
this.$set(_that.currRow, 'operationNo', operate.operationNo)
|
}
|
},
|
rowDrop() {
|
const that = this
|
const tbody = document.querySelector(
|
'#structureComponentTable .el-table__body-wrapper tbody'
|
)
|
Sortable.create(tbody, {
|
draggable: '.draggable-sort-row',
|
// 结束拖拽
|
onEnd({ newIndex, oldIndex }) {
|
if (newIndex > oldIndex) {
|
// 下移
|
that.nodeList
|
.filter((e) => e.lineItemNo === oldIndex + 1)
|
.forEach((e) => {
|
e.lineItemNo = 'x'
|
})
|
that.nodeList
|
.filter(
|
(e) =>
|
e.lineItemNo > oldIndex + 1 && e.lineItemNo <= newIndex + 1
|
)
|
.forEach((e) => {
|
e.lineItemNo = e.lineItemNo - 1
|
})
|
that.nodeList
|
.filter((e) => e.lineItemNo === 'x')
|
.forEach((e) => {
|
e.lineItemNo = newIndex + 1
|
})
|
} else if (oldIndex > newIndex) {
|
// 上移
|
that.nodeList
|
.filter((e) => e.lineItemNo === oldIndex + 1)
|
.forEach((e) => (e.lineItemNo = 'x'))
|
that.nodeList
|
.filter(
|
(e) =>
|
e.lineItemNo < oldIndex + 1 && e.lineItemNo >= newIndex + 1
|
)
|
.forEach((e) => (e.lineItemNo = e.lineItemNo + 1))
|
that.nodeList
|
.filter((e) => e.lineItemNo === 'x')
|
.forEach((e) => (e.lineItemNo = newIndex + 1))
|
}
|
|
const componentList = []
|
that.nodeList.forEach((e) => {
|
componentList.push({ id: e.id, lineItemNo: e.lineItemNo })
|
})
|
// 保存拖拽结果
|
that.batchUpdateNodeComponent(componentList)
|
}
|
})
|
},
|
addNode() {
|
if (this.dataForm.id != null) {
|
const templateNodeList = this.nodeList
|
this.nodeList = []
|
this.$nextTick(() => {
|
this.nodeList = templateNodeList
|
const newIndex = this.nodeList.length + 1
|
this.nodeList.push(
|
Object.assign({
|
id: null,
|
partId: 0,
|
partNo: '',
|
partName: '',
|
qpa: '',
|
unit: '',
|
drawingNumber: '',
|
structureId: this.dataForm.id,
|
isUpdate: true,
|
operationId: 0,
|
operationNo: '',
|
operationName: '',
|
discNum: '',
|
color: null,
|
planningMethod: null,
|
lineItemNo: newIndex
|
})
|
)
|
})
|
} else {
|
this.$message.warning('请先保存主表信息')
|
}
|
},
|
editNode(index, row) {
|
row.isUpdate = true
|
},
|
addOrUpdateNode(index, row) {
|
this.nodeSaveLoading = true
|
if (row.partId && row.qpa) {
|
// if (row.operationId) {
|
if (row.id != null) {
|
// 修改
|
putComponent(row)
|
.then((response) => {
|
if (response.data.code === 0) {
|
row.isUpdate = false
|
this.$message.success('修改成功')
|
} else {
|
this.$message.error('修改失败')
|
}
|
this.nodeSaveLoading = false
|
})
|
.catch((error) => {
|
this.nodeSaveLoading = false
|
console.log(error)
|
})
|
} else {
|
// 新增
|
addComponent(row)
|
.then((response) => {
|
if (response.data.code === 0) {
|
row.id = response.data.data
|
row.isUpdate = false
|
this.$message.success('添加成功')
|
} else {
|
this.$message.error('添加失败')
|
}
|
this.nodeSaveLoading = false
|
})
|
.catch((error) => {
|
this.nodeSaveLoading = false
|
console.log(error)
|
})
|
}
|
// } else {
|
// this.$message.warning('工序不能为空')
|
// }
|
} else {
|
this.nodeSaveLoading = false
|
this.$message.warning('零件和数量不能为空')
|
}
|
},
|
delNode(index, row) {
|
this.$confirm('是否确认删除零件号为' + row.partNo, '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
closeOnClickModal: false,
|
type: 'warning'
|
}).then(() => {
|
if (row.id) {
|
delComponent(row.id).then((response) => {
|
if (response.data.code === 0) {
|
this.nodeList.splice(
|
this.nodeList.findIndex(
|
(item) => item.lineItemNo === row.lineItemNo
|
),
|
1
|
)
|
const newNodelist = this.nodeList
|
this.nodeList = []
|
this.$nextTick(() => {
|
this.nodeList = newNodelist
|
const needChangeNodeList = []
|
this.nodeList
|
.filter((e) => e.lineItemNo >= row.lineItemNo)
|
.forEach((e) => {
|
e.lineItemNo = e.lineItemNo - 1
|
needChangeNodeList.push(e)
|
})
|
this.$message.success('删除成功')
|
// 找出nodeList中id不等于空的,进行顺序更新
|
const componentList = []
|
if (needChangeNodeList.length > 0) {
|
needChangeNodeList.forEach((e) => {
|
if (e.id != null) {
|
componentList.push({ id: e.id, lineItemNo: e.lineItemNo })
|
}
|
})
|
}
|
if (componentList.length > 0) {
|
this.batchUpdateNodeComponent(componentList)
|
}
|
})
|
} else {
|
this.$message.error('删除失败')
|
}
|
})
|
} else {
|
this.nodeList.splice(
|
this.nodeList.findIndex(
|
(item) => item.lineItemNo === row.lineItemNo
|
),
|
1
|
)
|
const newNodelist = this.nodeList
|
this.nodeList = []
|
this.$nextTick(() => {
|
this.nodeList = newNodelist
|
const needChangeNodeList = []
|
this.nodeList
|
.filter((e) => e.lineItemNo >= row.lineItemNo)
|
.forEach((e) => {
|
e.lineItemNo = e.lineItemNo - 1
|
needChangeNodeList.push(e)
|
})
|
this.$message.success('删除成功')
|
// 找出nodeList中id不等于空的,进行顺序更新
|
const componentList = []
|
if (needChangeNodeList.length > 0) {
|
needChangeNodeList.forEach((e) => {
|
if (e.id != null) {
|
componentList.push({ id: e.id, lineItemNo: e.lineItemNo })
|
}
|
})
|
}
|
if (componentList.length > 0) {
|
this.batchUpdateNodeComponent(componentList)
|
}
|
})
|
}
|
})
|
},
|
verifyPartNo(row, index) {
|
if (row.partNo) {
|
findByNo(Object.assign({ partNo: row.partNo })).then((response) => {
|
const part = response.data.data
|
if (response.data.data) {
|
this.$set(row, 'partId', part.id)
|
this.$set(row, 'partName', part.partName)
|
this.$set(row, 'unit', part.unit)
|
this.$set(row, 'drawingNumber', part.drawingNumber)
|
} else {
|
this.$set(this.customClass, index, 'el-input__red')
|
this.$message.warning('零件号不存在')
|
}
|
})
|
}
|
},
|
clearClass(index) {
|
this.$set(this.customClass, index, '')
|
},
|
checkPartNo() {
|
if (this.dataForm.partNo) {
|
findByNo(Object.assign({ partNo: this.dataForm.partNo })).then(
|
(response) => {
|
const part = response.data.data
|
if (response.data.data) {
|
this.dataForm.partId = part.id
|
this.dataForm.partName = part.partName
|
this.dataForm.version = part.version
|
} else {
|
this.dataForm.partNo = null
|
this.dataForm.partId = null
|
this.dataForm.partName = null
|
this.dataForm.version = null
|
this.$message.warning('零件号不存在')
|
}
|
}
|
)
|
}
|
},
|
// 批量更新子节点
|
batchUpdateNodeComponent(componentList) {
|
batchComponent(componentList).then((response) => {})
|
},
|
// 判断是否禁用行拖拽排序,只有所有行都进行save之后,才能进行排序。
|
structureComponentRowClass() {
|
if (this.nodeList.length > 0) {
|
let forbidFlag = false
|
this.nodeList.forEach((e) => {
|
if (e.id == null) {
|
forbidFlag = true
|
}
|
})
|
if (forbidFlag) {
|
return ''
|
} else {
|
return 'draggable-sort-row'
|
}
|
} else {
|
return ''
|
}
|
}
|
}
|
}
|
</script>
|
<style>
|
.single-structure-basic {
|
background-color: #fff;
|
height: 100px;
|
display: flex;
|
padding: 20px 30px;
|
border: 1px solid #ddd;
|
box-sizing: border-box;
|
}
|
.single-structure-detail {
|
overflow: hidden;
|
width: 100%;
|
height: 760px;
|
padding: 10px 20px;
|
display: flex;
|
border: 1px solid #ddd;
|
background-color: #fff;
|
margin-top: 10px;
|
box-sizing: border-box;
|
}
|
.single-structure-card {
|
width: 100%;
|
border: 0px;
|
}
|
.single-structure-card .el-card__header {
|
border-bottom: 0px;
|
}
|
.single-structure-card .el-card__body {
|
padding-top: 0px;
|
}
|
.blue-but.is-disabled {
|
color: #aacfff;
|
}
|
|
.blue-but {
|
color: #006eff;
|
}
|
.red-but.is-disabled {
|
color: #fab6b6;
|
}
|
|
.red-but {
|
color: red;
|
}
|
|
.el-input__red {
|
border: 1px solid red;
|
}
|
</style>
|