This commit is contained in:
2021-09-13 14:56:28 +08:00
commit ac0d6e9083
777 changed files with 90286 additions and 0 deletions

View File

@@ -0,0 +1,144 @@
<!--
* @Author: zwq
* @Date: 2020-12-29 16:37:56
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-07-26 14:39:36
* @Description:
-->
<template>
<el-dialog
:title="!dataForm.id ? 'btn.add' : 'btn.edit' | i18nFilter"
:visible.sync="visible"
>
<el-form ref="dataForm" :model="dataForm" :rules="dataRule" label-width="190px" @keyup.enter.native="dataFormSubmit()">
<el-form-item :label="$t('module.art.processList.processName')" prop="name">
<el-input v-model="dataForm.name" :placeholder="$i18nForm(['placeholder.input', $t('module.art.processList.processName')])" clearable />
</el-form-item>
<el-form-item :label="$t('module.art.processList.processEq')" prop="equipmentIds">
<el-select v-model="dataForm.equipmentIds" clearable filterable multiple>
<el-option v-for="item in eqList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item :label="$t('module.art.processList.type')" prop="type">
<el-select v-model="dataForm.type" clearable filterable>
<el-option v-for="item in typeList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item :label="$t('module.art.processList.description')" prop="address">
<el-input v-model="dataForm.description" :placeholder="$i18nForm(['placeholder.input', $t('module.art.processList.description')])" clearable />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="visible = false">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="dataFormSubmit()">{{ 'btn.confirm' | i18nFilter }}</el-button>
</span>
</el-dialog>
</template>
<script>
import { getInfo, add, update } from '@/api/art-manage/process'
import i18n from '@/lang'
const typeList = [
{ id: 0, name: i18n.t('module.art.processList.equipment') },
{ id: 1, name: i18n.t('module.art.processList.buffer') }
]
export default {
props: {
eqList: {
type: Array,
default: () => {
return []
}
}
},
data() {
return {
visible: false,
dataForm: {
id: 0,
name: '',
type: null,
equipmentIds: [],
description: ''
},
dataRule: {
name: [
{
required: true,
message: this.$i18nForm(['placeholder.input', this.$t('module.art.processList.processName')]),
trigger: 'blur' }
],
equipmentIds: [
{
required: true,
message: this.$i18nForm(['placeholder.select', this.$t('module.art.processList.processEq')]),
trigger: 'blur' }
]
},
typeList
}
},
methods: {
init(id) {
this.dataForm.id = id || null
this.visible = true
this.$nextTick(() => {
this.$refs['dataForm'].resetFields()
if (this.dataForm.id) {
getInfo({ id: this.dataForm.id }).then(res => {
this.dataForm.id = res.data.id
this.dataForm.name = res.data.name
this.dataForm.type = res.data.type
this.dataForm.description = res.data.description
this.dataForm.equipmentIds = res.data.equipments.map(item => {
return item.id
})
})
}
})
},
// 表单提交
dataFormSubmit() {
console.log(!this.dataForm.id)
this.$refs['dataForm'].validate((valid) => {
if (valid) {
const data = {
'name': this.dataForm.name,
'type': this.dataForm.type,
'equipmentIds': this.dataForm.equipmentIds,
'description': this.dataForm.description,
'id': this.dataForm.id
}
if (this.dataForm.id) {
update(data).then(res => {
this.$message({
message: this.$t('module.basicData.visual.success'),
type: 'success',
duration: 1500,
onClose: () => {
this.visible = false
this.$emit('refreshDataList')
}
})
})
} else {
add(data).then(res => {
this.$message({
message: this.$t('module.basicData.visual.success'),
type: 'success',
duration: 1500,
onClose: () => {
this.visible = false
this.$emit('refreshDataList')
}
})
})
}
}
})
}
}
}
</script>

View File

@@ -0,0 +1,189 @@
<template>
<el-dialog
:close-on-click-modal="false"
:close-on-press-escape="false"
width="25%"
:visible="visible"
:destroy-on-close="true"
:before-close="() => $emit('on-close')"
:title="id ? 'btn.edit' : 'btn.add' | i18nFilter"
:class="$style.dialog"
>
<el-form ref="obj" :model="obj" :rules="rules" label-width="140px">
<el-form-item :label="$t('module.art.artName')" prop="name">
<el-input v-model="obj.name" />
</el-form-item>
<el-form-item :label="$t('module.art.externalCode')" prop="externalCode">
<el-input v-model="obj.code" />
</el-form-item>
<!-- <el-form-item :label="$t('module.art.substrateType')" prop="substrateId">
<el-select
v-model="obj.substrateId"
:class="$style.select"
filterable
clearable
:placeholder="'placeholder.select' | i18nFilter"
>
<el-option
v-for="item in substrateList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item> -->
<el-form-item v-if="false" :label="$t('module.art.artBOM')" prop="bomId">
<el-select
v-model="obj.bomId"
:class="$style.select"
filterable
clearable
:placeholder="'placeholder.select' | i18nFilter"
>
<el-option
v-for="item in bomList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('module.art.description')" prop="description">
<el-input v-model="obj.description" />
</el-form-item>
<el-form-item :label="$t('module.art.remark')" prop="remark">
<el-input v-model="obj.remark" />
</el-form-item>
<SubmitBar
@on-cancle="$emit('on-close')"
@on-submit="handleSubmit('obj')"
/>
</el-form>
</el-dialog>
</template>
<script>
import { add, update, getInfo, listSubstrate, listBom, getCode } from '@/api/art-manage/art.js'
import SubmitBar from '@/views/art/components/submit-bar'
export default {
name: 'AddDialog',
components: {
SubmitBar
},
props: {
visible: {
type: Boolean,
default: false
},
id: {
type: String,
default: null
}
},
data() {
return {
obj: {
name: '',
code: '',
remark: '',
description: '',
substrateId: '',
bomId: ''
},
substrateList: [],
bomList: [],
rules: {
name: [
{ required: true, message: this.$t('module.art.artName') + this.$t('module.art.notNull'), trigger: 'blur' },
{ min: 3, message: this.$t('module.art.lengthRule'), trigger: 'blur' }
],
// externalCode: [
// { required: true, message: this.$t('module.art.externalCode') + this.$t('module.art.notNull'), trigger: 'blur' },
// { min: 3, message: this.$t('module.art.lengthRule'), trigger: 'blur' }
// ],
// substrateId: [
// {
// required: true,
// message: this.$t('module.art.selectNotNull') + this.$t('module.art.substrateType'),
// trigger: 'change'
// }
// ],
bomId: [
{
required: true,
message: this.$t('module.art.selectNotNull') + this.$t('module.art.artBOM'),
trigger: 'change'
}
]
}
}
},
watch: {
id(val) {
this.init()
}
},
created() {
this.init()
},
methods: {
init: async function() {
if (this.substrateList.length === 0) {
const substrateRes = await listSubstrate()
this.substrateList = substrateRes.data
}
if (this.bomList.length === 0) {
const bomRes = await listBom()
this.bomList = bomRes.data
}
if (this.id) {
const res = await getInfo({ id: this.id })
this.obj = res.data
} else {
const result = await getCode()
this.obj = {
name: '',
code: result.data,
remark: '',
description: '',
substrateId: '',
bomId: ''
}
}
},
handleSubmit(formName) {
this.$refs[formName].validate((valid) => {
if (!valid) {
return false
}
console.log(this.obj)
if (this.id) {
update(this.obj).then(res => {
this.$emit('on-success')
})
} else {
add(this.obj).then(res => {
this.$emit('on-success')
})
}
})
}
}
}
</script>
<style lang="scss" module>
.dialog {
.input {
display: flex;
margin: 8px 16px 8px 4px;
align-items: center;
.select {
width: 100%;
}
}
.select {
width: 100%;
}
}
</style>

View File

@@ -0,0 +1,39 @@
<template>
<div :class="$style.container">demo</div>
</template>
<script>
export default {
name: 'Demo',
components: {
},
props: {
visible: {
type: Boolean,
default: false
}
},
data() {
return {
}
},
methods: {
}
}
</script>
<style lang="scss" module>
.container {
.input {
display: flex;
margin: 8px 16px 8px 4px;
align-items: center;
.select {
width: 100%;
}
}
.select {
width: 100%;
}
}
</style>

View File

@@ -0,0 +1,40 @@
<template>
<VueScrollbar :class="$style.c" @click="$emit('on-detail')">
<div :class="$style.chart">
sssss
</div>
</VueScrollbar>
</template>
<script>
import VueScrollbar from 'vue-perfect-scrollbar'
export default {
name: 'ProcessChart',
components: { VueScrollbar },
props: {
visible: {
type: Boolean,
default: false
}
},
data() {
return {}
},
mounted() {
},
methods: {}
}
</script>
<style lang="scss" module>
.c {
margin: 16px;
height: 300px;
width: 10%;
position: relative;
.chart {
position: relative;
height: 400px;
width: 120%;
}
}
</style>

View File

@@ -0,0 +1,74 @@
<template>
<el-drawer
title="工艺流程图"
size="85%"
:append-to-body="true"
:visible.sync="visible"
:wrapper-closable="false"
:before-close="() => $emit('on-close')"
>
<ProcessEditBar :is-edit="isEdit" @on-edit="isEdit=true" @on-cancel="isEdit=false" @on-submit="handleSubmit()" />
<ProcessChart v-show="!isEdit" @on-detail="handleDetail" />
<ProcessTable v-if="isEdit" :process-flow-id="processFlowId" @on-detail="handleDetail" />
<el-drawer
title="节点详情"
size="20%"
:append-to-body="true"
:before-close="()=>innerDrawer=false"
:visible.sync="innerDrawer"
>
<ProcessNodePanel />
</el-drawer>
</el-drawer>
</template>
<script>
import ProcessChart from '@/views/art/components/process-chart'
import ProcessTable from '@/views/art/components/process-table'
import ProcessNodePanel from '@/views/art/components/process-node-panel'
import ProcessEditBar from '@/views/art/components/process-edit-bar'
export default {
name: 'ProcessDrawer',
components: { ProcessChart, ProcessTable, ProcessNodePanel, ProcessEditBar },
props: {
visible: {
type: Boolean,
default: false
},
processFlowId: {
type: String,
default: null
}
},
data() {
return {
innerDrawer: false,
isEdit: false
}
},
methods: {
handleDetail() {
this.innerDrawer = true
},
handleSubmit() {
console.log('保存成功')
this.isEdit = false
}
}
}
</script>
<style lang="scss" module>
.dialog {
.input {
display: flex;
margin: 8px 16px 8px 4px;
align-items: center;
.select {
width: 100%;
}
}
.select {
width: 100%;
}
}
</style>

View File

@@ -0,0 +1,62 @@
<!--
* @Author: gtz
* @Date: 2021-01-27 10:07:42
* @LastEditors: gtz
* @LastEditTime: 2021-02-01 11:28:16
* @Description: file content
-->
<template>
<div :class="$style.container">
<el-button
v-show="!isEdit"
type="primary"
size="mini"
icon="el-icon-edit"
@click="$emit('on-edit')"
>
{{ 'btn.edit' | i18nFilter }}
</el-button>
<el-button
v-show="isEdit"
type="success"
size="mini"
icon="el-icon-s-promotion"
@click="$bus.emit('on-process-save')"
>
{{ 'btn.save' | i18nFilter }}
</el-button>
<el-button
v-show="isEdit"
icon="el-icon-close"
size="mini"
@click="$emit('on-cancel')"
>
{{ 'btn.cancel' | i18nFilter }}
</el-button>
<slot />
</div>
</template>
<script>
export default {
props: {
isEdit: {
type: Boolean,
default: false
}
},
data() {
return {}
},
methods: {}
}
</script>
<style lang="scss" module>
.container {
background-color: #eee;
display: flex;
justify-content: flex-start;
padding: 4px 16px;
margin: -16px 16px 16px 16px;
width: 98%;
}
</style>

View File

@@ -0,0 +1,90 @@
<template>
<div :class="$style.container">
<div :class="$style.content">
<el-divider>
<span>设备信息</span>
</el-divider>
<div>
<span>设备名称</span>
<span>设备A</span>
</div>
<div>
<span>设备名称</span>
<span>设备A</span>
</div>
<div>
<span>设备名称</span>
<span>设备A</span>
</div>
</div>
<div :class="$style.content">
<el-divider><span>配方清单</span></el-divider>
<div>
<span>设备名称</span>
<span>设备A</span>
</div>
<div>
<span>设备名称</span>
<span>设备A</span>
</div>
<div>
<span>设备名称</span>
<span>设备A</span>
</div>
</div>
<div :class="$style.content">
<el-divider><span>物料清单</span></el-divider>
<div>
<span>设备名称</span>
<span>设备A</span>
</div>
<div>
<span>设备名称</span>
<span>设备A</span>
</div>
<div>
<span>设备名称</span>
<span>设备A</span>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Demo',
components: {
},
props: {
visible: {
type: Boolean,
default: false
}
},
data() {
return {
}
},
methods: {
}
}
</script>
<style lang="scss" module>
.container {
margin: 0px 16px;
.content {
padding:0 16px;
font-size: 14px;
div{
margin-bottom: 8px;
span:nth-of-type(odd){
color:#999;
}
span:nth-of-type(even){
color:#666;
}
}
}
}
</style>

View File

@@ -0,0 +1,325 @@
<template>
<VueScrollbar :class="$style.content">
<div :class="$style['flaw-detail']">
<div :class="$style['flaw-title']">
设备名称
</div>
<div :class="$style['flaw-title']">
配方名称
</div>
<div :class="$style['flaw-title']">
物料bom
</div>
<div :class="$style['flaw-title']">
工艺类型
</div>
<div :class="$style['flaw-title']">
描述
</div>
<div :class="$style['flaw-title']">
备注
</div>
<div :class="$style['flaw-btns']">
<el-button
type="success"
icon="el-icon-plus"
circle
@click="flawAdd()"
/>
</div>
</div>
<div
v-for="(item, index) in process.processFlowEquipmentParams"
:key="index"
:class="$style['flaw-detail']"
>
<el-select
v-model="item.equipmentId"
:class="$style['flaw-select']"
filterable
clearable
placeholder="请选择"
@change="equipmentChange($event, item)"
>
<el-option
v-for="equipment in equipmentList"
:key="equipment.id"
:label="equipment.name"
:value="equipment.id"
/>
</el-select>
<el-select
v-model="item.equipmentRecipeId"
:class="$style['flaw-select']"
filterable
clearable
placeholder="请选择"
>
<el-option
v-for="param in item.params"
:key="param.id"
:label="param.name"
:value="param.id"
/>
</el-select>
<el-select
v-model="item.equipmentBomId"
:class="$style['flaw-select']"
filterable
clearable
placeholder="请选择"
>
<el-option
v-for="bom in item.boms"
:key="bom.id"
:label="bom.name"
:value="bom.id"
/>
</el-select>
<el-select
v-model="item.nodeType"
:class="$style['flaw-select']"
filterable
clearable
placeholder="请选择"
>
<el-option
v-for="nodeType in nodeTypes"
:key="nodeType.value"
:label="nodeType.label"
:value="nodeType.value"
/>
</el-select>
<el-input v-model="item.description" :class="$style['flaw-select']" />
<el-input v-model="item.remark" :class="$style['flaw-select']" />
<el-button
type="success"
icon="el-icon-plus"
circle
@click="flawAdd(item)"
/>
<el-button
type="danger"
icon="el-icon-delete"
circle
@click="flawDel(item)"
/>
<el-button
type="info"
icon="el-icon-document"
circle
@click="$emit('on-detail', item)"
/>
</div>
</VueScrollbar>
</template>
<script>
import {
listAllEquipmentBom,
listAllEquipmentRecipe,
addProcessFlows,
listProcessFlowNode
} from '@/api/art-manage/art.js'
import { listEquipment } from '@/api/material-manage/material'
import remove from 'lodash/remove.js'
import findIndex from 'lodash/findIndex.js'
import VueScrollbar from 'vue-perfect-scrollbar'
export default {
name: 'ProcessTable',
components: { VueScrollbar },
props: {
processFlowId: {
type: String,
default: null
}
},
data() {
return {
defaultFlaws: [],
process: {
processFlowId: this.processFlowId,
processFlowEquipmentParams: [
{
equipmentId: null,
equipmentRecipeId: null,
equipmentBomId: null,
nodeType: null,
processFlowId: this.processFlowId,
remark: null,
description: null,
boms: [],
params: []
}
]
},
currentFlawRow: {},
productDetBarcode: '',
warehouseBarcode: '',
equipmentList: [],
equipmentBomList: [],
equipmentParamList: [],
// 1、上片设备2、加工设备3、下片设备
nodeTypes: [
{
value: '1',
label: '上片设备'
},
{
value: '2',
label: '加工设备'
},
{
value: '3',
label: '下片设备'
}
]
}
},
created() {
this.init()
this.$bus.on('on-process-save', this.save)
},
beforeDestroy() {
this.$bus.off('on-process-save', this.save)
},
mounted() {},
methods: {
flawAdd(item) {
const mid = [
{
equipmentId: null,
equipmentRecipeId: null,
equipmentBomId: null,
nodeType: null,
processFlowId: this.processFlowId,
remark: null,
description: null,
boms: [],
params: []
}
]
if (!item) {
this.process.processFlowEquipmentParams = mid.concat(
this.process.processFlowEquipmentParams
)
return
}
const index = findIndex(
this.process.processFlowEquipmentParams,
f => f === item
)
console.log(index)
const { length } = this.process.processFlowEquipmentParams
const beg = this.process.processFlowEquipmentParams.slice(0, index + 1)
const end = this.process.processFlowEquipmentParams.slice(
index + 1,
length
)
this.process.processFlowEquipmentParams = [].concat(beg, mid, end)
},
flawDel(item) {
console.log(item)
remove(this.process.processFlowEquipmentParams, f => f === item)
console.log(this.process.processFlowEquipmentParams)
this.process.processFlowEquipmentParams = this.process.processFlowEquipmentParams.concat(
[]
)
},
focusFlaw(item) {
console.log(item)
this.currentFlawRow = item
},
setFlaw(flaw) {
console.log(flaw)
this.currentFlawRow.description = flaw.defectName
this.currentFlawRow.fabricId = flaw.id
},
reset() {
console.log(this.defaultFlaws)
this.process.processFlowEquipmentParams = JSON.parse(
JSON.stringify(this.defaultFlaws)
)
},
save() {
const vm = this
console.log(JSON.stringify(vm.process))
if (vm.process.processFlowEquipmentParams.length === 0) {
vm.$alert('工艺节点为空,您确定要保存吗?', '[温馨提示]', {
confirmButtonText: '确定',
callback: action => {
console.log('保存')
addProcessFlows(vm.process)
}
})
} else {
addProcessFlows(vm.process)
}
},
async init() {
const allBomRes = await listAllEquipmentBom()
this.equipmentBomList = allBomRes.data
const allRecipeRes = await listAllEquipmentRecipe()
this.equipmentParamList = allRecipeRes.data
const allEquipmentRes = await listEquipment()
this.equipmentList = allEquipmentRes.data
const allNodeRes = await listProcessFlowNode({ processFlowId: this.processFlowId })
console.log(allNodeRes)
const allNodes = allNodeRes.data
console.log(allNodes)
if (allNodes && allNodes.length === 0) {
return
}
this.process.processFlowEquipmentParams = allNodes.map(m => {
return {
...m,
nodeType: null,
processFlowId: this.processFlowId,
boms: this.equipmentBomList.filter(f => f.equipmentId === m.equipmentId),
params: this.equipmentParamList.filter(f => f.equipmentId === m.equipmentId),
id: null
}
})
console.log(this.process.processFlowEquipmentParams)
},
equipmentChange(val, item) {
console.log(val, item)
item.boms = this.equipmentBomList.filter(f => f.equipmentId === val)
item.params = this.equipmentParamList.filter(f => f.equipmentId === val)
}
}
}
</script>
<style lang="scss" module>
$colWidth: 200px;
.content {
padding: 16px;
margin: 16px;
position: relative;
height: calc(100vh - 150px);
.flaw-detail {
width: 1400px;
position: relative;
display: flex;
align-items: center;
.flaw-title {
position: relative;
width: $colWidth;
text-align: center;
border: 1px solid #ccc;
background-color: #eee;
padding: 8px;
}
.flaw-btns {
position: relative;
width: $colWidth;
text-align: left;
}
.flaw-select {
position: relative;
width: $colWidth;
height: 40px;
}
}
}
</style>

View File

@@ -0,0 +1,124 @@
<template>
<div class="container">
<span class="label-name">{{ $t('module.teamManager.Handover.Keyword') }}</span>
<el-input
v-model="keywords"
:placeholder="placeholder"
:clearable="true"
:style="{
width: inputWidth + 'px',
maxWidth: '100%',
marginRight: '16px'
}"
/>
<el-date-picker
v-if="showTime"
v-model="dts"
style="margin-right:16px;"
type="daterange"
align="right"
unlink-panels
:range-separator="'formItem.to' | i18nFilter"
:start-placeholder="'formItem.beginTime' | i18nFilter"
:end-placeholder="'formItem.endTime' | i18nFilter"
:picker-options="pickerOptions"
/>
<el-button type="primary" icon="el-icon-search" @click="handleSearch()">
{{ "btn.search" | i18nFilter }}
</el-button>
<slot />
</div>
</template>
<script>
import moment from 'moment'
import i18n from '@/lang'
const pickerOptions = {
shortcuts: [
{
text: i18n.t('datePickerOption.lastWeek'),
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
picker.$emit('pick', [start, end])
}
},
{
text: i18n.t('datePickerOption.lastMonth'),
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
picker.$emit('pick', [start, end])
}
},
{
text: i18n.t('datePickerOption.lastThreeMonths'),
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
picker.$emit('pick', [start, end])
}
}
]
}
export default {
props: {
showTime: {
type: Boolean,
default: false
},
lableName: {
type: String,
default: '关键字'
},
placeholder: {
type: String,
default: '请输入'
},
inputWidth: {
type: Number,
default: 180
}
},
data() {
return {
keywords: '',
dts: ['', ''],
pickerOptions
}
},
methods: {
handleSearch() {
const param = {
keywords: this.keywords,
key: this.keywords,
begDate: this.dts[0]
? moment(this.dts[0]).format('YYYY-MM-DD')
: this.dts[0],
endDate: this.dts[1]
? moment(this.dts[1]).format('YYYY-MM-DD')
: this.dts[1]
}
this.$emit('on-search', param)
}
}
}
</script>
<style lang="scss" scoped>
.container {
display: flex;
align-items: center;
width: 100%;
height: 50px;
padding: 4px 40px;
background-color: #eee;
.label-name {
margin-right: 8px;
font-size: 14px;
}
}
</style>

View File

@@ -0,0 +1,38 @@
<!--
* @Author: gtz
* @Date: 2021-01-27 10:07:42
* @LastEditors: gtz
* @LastEditTime: 2021-02-01 11:26:16
* @Description: file content
-->
<template>
<div :class="$style.container">
<el-button type="primary" icon="el-icon-success" @click="$emit('on-submit')">
{{ 'btn.confirm' | i18nFilter }}
</el-button>
<el-button icon="el-icon-close" @click="$emit('on-cancle')">
{{ 'btn.cancel' | i18nFilter }}
</el-button>
<slot />
</div>
</template>
<script>
export default {
props: {
},
data() {
return { }
},
methods: {
}
}
</script>
<style lang="scss" module>
.container {
display: flex;
justify-content: center;
margin-top:28px;
width: 100%;
height: 40px;
}
</style>