You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

746 lines
25 KiB

<template>
<Dialog
:title="dialogTitle"
v-model="dialogVisible"
:width="dialogWidth"
:close-on-click-modal="false"
:vLoading="formLoading"
>
<ContentWrap>
<Descriptions
:data="detailData"
labelClassName="label-class-name"
label-align="left"
direction="vertical"
:column="8"
:schema="allSchemas.detailSchema"
:columns="2"
width="200px"
/>
</ContentWrap>
<ContentWrap>
<el-container>
<el-aside width="320px">
<el-card>
<template #header>
<div class="card-header">
<span>工艺路线</span>
<!-- <el-button
type="text"
icon="el-icon-plus"
@click="opensearchTable"
style="float: right; padding: 3px 0"
>添加工序</el-button> -->
</div>
</template>
<el-table :data="processData" ref="tableProcess" style="width: 100%; height: 80%" @cell-dblclick="userAddNode">
<el-table-column prop="code" label="工序编码" />
<el-table-column prop="name" label="工序名称" />
<!-- <el-table-column prop="opera" label="" width="60">
<template #header>
<span>操作</span>
</template>
<template #default="scope">
<el-button type="danger" size="mini" text @click="deleteNode(scope.row)"
>移除</el-button
>
</template>
</el-table-column> -->
</el-table>
</el-card>
</el-aside>
<el-main style="height: 480px; width: calc(100% - 980px);padding: 0px; margin:0px 20px">
<div ref="graphContainer"></div
></el-main>
<el-aside width="640px">
<el-tag>工序编码:{{currentNode.id}} -工序名称:{{currentNode.name }}</el-tag>
<el-tabs v-model="activeName" >
<el-tab-pane label="工序工位" name="workstation">
<el-table :data="workstationData" ref="tableWorkstations" style="width: 100%; height: 80%">
<el-table-column prop="stationName" label="工位名称" />
<el-table-column prop="processCode" label="工序编码" />
<!-- <el-table-column prop="stationName" label="工作位置">-->
<!-- <template #default="scope">-->
<!-- <el-button size="mini" text style="width: 100%"-->
<!-- >{{ scope.row.name }}[{{ scope.row.code }}]</el-button-->
<!-- >-->
<!-- </template>-->
<!-- </el-table-column>-->
</el-table>
</el-tab-pane>
<el-tab-pane label="工序物料" name="materials">
<el-table :data="showMaterialsData" ref="tableMaterials" style="width: 100%; height: 80%">
<el-table-column prop="repMaterialCode" label="物料编码" />
<el-table-column prop="repMaterialCounts" label="物料数量" />
<el-table-column prop="repMaterialModel" label="物料单位" />
<el-table-column prop="sourceMaterialCounts" label="需求物料数">
<template #default="scope">{{ getTotalcounts(scope.row.repMaterialCounts) }}</template>
</el-table-column>
<el-table-column prop="replaceFlag" label="是否替换" >
<template #default="scope">
<el-switch
v-model="scope.row.replaceFlag"
active-color="#13ce66"
inactive-color="#ff4949"
active-text="是"
inactive-text="否"
/>
</template>
</el-table-column>
</el-table>
<el-pagination
small
hide-on-single-page="true"
layout="prev, pager, next"
:total="page.total"
:page-size="page.size"
:current-page="page.current"
@current-change="handleCurrentChangeM"
@prev-click="handlePrevClickM"
@next-click="handleNextClickM"
/>
</el-tab-pane>
<el-tab-pane label="工序人员" name="workers">
<el-button type="primary" @click="opensearchTableUser">添加人员</el-button>
<el-button type="success" @click="saveUser">保存</el-button>
<el-table :data="workerData" ref="tableWorker" style="width: 100%; height: 233px;overflow: auto;">
<el-table-column prop="groupName" label="所属班组" />
<el-table-column prop="workerMonitor" label="班长" />
<el-table-column prop="workerCode" label="人员编码" />
<el-table-column prop="workerName" label="人员昵称" />
<el-table-column prop="opera" label="" width="70" >
<template #header>
<span>操作</span>
</template>
<template #default="scope">
<el-button type="danger" size="mini" text @click="deleteUser(scope.row)" style="margin-right: 20px">移除</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="工序设备" name="equipments">
<el-button type="primary" @click="opensearchTableEquipment">添加设备</el-button>
<el-button type="success" @click="saveEquipment">保存</el-button>
<el-table :data="equipmentData" ref="tableEquipment" style="width: 100%; height: 80%">
<el-table-column prop="equipmentCode" label="设备编码" />
<el-table-column prop="equipmentName" label="设备名称" />
<el-table-column prop="equipmentType" label="设备类型" />
<el-table-column prop="equipmentWorkstation" label="关联工位" />
<!-- <el-table-column prop="equipmentOper" label="操作说明" />-->
<el-table-column prop="opera" label="" width="70" >
<template #header>
<span>操作</span>
</template>
<template #default="scope">
<el-button type="danger" size="mini" text @click="deleteEquipment(scope.row)" style="margin-right: 20px">移除</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
</el-aside>
</el-container>
<el-dialog v-model="dialogFormVisibleUser" title="请选择班组" width="600" :style="{ 'padding': '15px' }">
<el-row>
<el-col :span="8">
<el-form-item label="班组类型">
<el-select v-model="filterFormTeam.teamGroup" placeholder="请选择类型">
<el-option label="生产班组" value="1" />
<el-option label="维修班组" value="2" />
<el-option label="质检班组" value="3" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="班组名称" style="margin-left: 15px">
<el-input v-model="filterFormTeam.teamName" placeholder="请输入名称" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item>
<el-button type="primary" @click="searchTeamList" style="margin-left: 15px">查询</el-button>
</el-form-item>
</el-col>
</el-row>
<!-- 表格内容 -->
<content-wrap>
<el-table highlight-current-row :data="teamData" style="width: 100%">
<el-table-column prop="code" label="班组编码" />
<el-table-column prop="name" label="班组名称" />
<el-table-column prop="teamGroup" label="班组类型" >
<template #default="scope">
<el-select v-model="scope.row.teamGroup" placeholder="请选择班组类型" disabled="true">
<el-option
v-for="item in teamGroupOptions"
:key="item.value"
:label="item.label"
:value="item.value"/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="name" label="操作" >
<template #default="scope">
<el-button type="text" @click="handleConfirm(scope.row)">选择成员</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
v-model:current-page="currentPage"
:page-size="5"
layout="total, prev, pager, next"
:total="totalTeam"
@current-change="handleCurrentChange"
/>
</content-wrap>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeTeamUser">关闭</el-button>
</div>
</template>
</el-dialog>
</ContentWrap>
<template #footer>
<el-button @click="dialogVisible=false" >关闭</el-button>
<el-button type="primary" @click="publishPlan" >发布计划</el-button>
</template>
<SearchTable ref="searchTableRef" @search-table-success="searchTableSuccess" />
</Dialog>
<!-- <SearchTable ref="searchTableRef" @searchTableSuccess="searchTableSuccess" /> -->
</template>
<script lang="ts" setup>
import {
start_node,
end_node,
createGraph,
getNewNode
} from '@/views/mes/processroute/components/graphbase.data'
import * as orderDayconfigApi from '@/api/mes/orderDayConfig'
import * as OrderDayApi from '@/api/mes/orderDay'
import {ProcessSearch} from '../../publicUtil/processSearch.data'
import * as ProcessApi from '@/api/wms/process'
import { SearchTable } from '@/components/SearchTable'
import { Graph } from '@antv/x6'
import * as TeamApi from '@/api/wms/team'
import {searchUser} from "@/views/wms/basicDataManage/orderManage/team/team.data";
import {getStrDictOptions} from "@/utils/dict";
import {Equipment} from "@/views/mes/workstation/workstation.data";
import * as WorkstationApi from "@/api/mes/workstation";
import {DeviceInfo, OrderDay} from "@/views/mes/orderDay/orderDay.data";
//import {TableForm} from '@/components/TableForm/src/TableForm.vue' // 引入TableForm.vue组件
const graphContainer = ref<HTMLElement | null>(null)
const graph = ref<Graph>()
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const activeName = ref('workstation')
const formLoading = ref(false)
const dialogFormVisibleUser = ref(false)
const processData = ref([])
const processCode = ref('')
//const isPublish=ref(false)
const queryParams:orderDayconfigApi.OrderDayQueryParamVo=ref()
const props = defineProps({
// 查询弹窗是否显示筛选按钮
isSearchFilterButtonHide: {
type: Boolean,
default: false
},
// 显示窗口宽度设置
basicFormWidth: {
type: String,
default: ''
},
allSchemas: {
type: Object,
required: true,
default: null
}
})
const detailData = ref(props.allSchemas)
const route = useRoute() // 路由信息
const routeName = ref()
routeName.value = route.name
routeName.value = routeName.value.substring(0, routeName.value.length - 4) + 'Detail'
//const updateKey = ref(0)
const dialogWidth = ref()
const materialsData = ref()
const equipmentData=ref([])
const workstationData=ref([])
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const graphJson =ref()
const currentNode = ref({
name:'',
id:''
})
const showMaterialsData=ref() //物料信息分页展示
const page=ref({
total:0,
current:1,
size:5
})
/*班组数据*/
const teamData = ref([])
/*班组弹窗搜索条件*/
const filterFormTeam = ref({
teamGroup: '',
teamName: '',
})
/*班组信息分页参数*/
const totalTeam = ref(0);
const currentPage =ref(1)
/*关闭班组弹窗*/
const closeTeamUser = () =>{
dialogFormVisibleUser.value = false
filterFormTeam.value ={
teamGroup: '',
teamName: ''
}
}
/*通过班组选择的人员数据集*/
const workerData=ref([])
/*查询班组接口参数*/
const teamParams = ref({
workshopCode:'',
productionLineCode:'',
teamGroup: '',
name: '',
pageNo:1,
pageSize:5
});
/*班组类型数据集*/
const teamGroupOptions = ref([])
const getOptions=()=>{
teamGroupOptions.value=getStrDictOptions(DICT_TYPE.BASIC_TEAM_TYPE)
}
/*班组分页调用的接口*/
const handleCurrentChange = (val: number) => {
currentPage.value = val
searchTeamListCommon()
}
const searchTeamList = () => {
currentPage.value = 1
searchTeamListCommon()
}
/** 打开弹窗 */
const open = async (type: string, row?: any, titleName?: any) => {
currentNode.value.name=''
currentNode.value.id=''
//首次打开页面,将数据清空
workerData.value = []
equipmentData.value = []
materialsData.value = []
showMaterialsData.value=[]
page.value.total = 0
page.value.current = 1
workstationData.value = []
getOptions()
dialogVisible.value = true
detailData.value = row
dialogWidth.value = props.basicFormWidth + '%'
queryParams.planNoDay=row.planNoDay
queryParams.productCode=row.productCode
queryParams.workroomCode=row.workroomCode
queryParams.lineCode=row.lineCode
queryParams.processrouteCode=row.processrouteCode
queryParams.batchCode=row.batchCode
//获取配置的
if (titleName) {
dialogTitle.value = titleName
} else {
dialogTitle.value = type
}
nextTick?.(() => {
graph.value = createGraph(graphContainer.value as HTMLElement, true, 240, 320)
graph.value.on('node:click', ({ e, x, y, node, view }) => {
nodeClick(e, x, y, node, view)
})
getProcessroute()
getConfigProcessRouteNode()
})
}
const getTotalcounts=(a:any)=>{
return detailData.value.planCount*a
}
//添加节点
const userAddNode = (row) => {
if (graph && graph.value != undefined) {
let node_template = getNewNode(row.code, row.name, row.code)
node_template.x = end_node.value.x - 100
node_template.y = end_node.value.y + 100
let noden = graph.value.addNode(node_template)
if (graph.value.getNodes().length == 1) {
let start = graph.value.addNode(start_node.value)
let end = graph.value.addNode(end_node.value)
graph.value.addEdge({
id: 'startEdge',
source: start.id, // 源节点 ID
target: noden.id
})
graph.value.addEdge({
id: 'endEdge',
source: noden.id, // 源节点 ID
target: end.id
})
}
}
}
//获取工序的BOM
const getProcessBom=async (code:any) => {
queryParams.processCode=code
let res = await orderDayconfigApi.getOrderDayBomByOrder(queryParams)
materialsData.value=res
if(materialsData.value.length>0){
page.value.total = materialsData.value.length
page.value.current = 1
showMaterialsData.value=materialsData.value.slice(0,page.value.size)
}
}
// const currentStartNode = ref({
// id:''
// })
//获取配置的工艺路线信息
const getProcessroute = async () => {
let res = await orderDayconfigApi.getConfigProcessRoute(queryParams)
graphJson.value=JSON.parse(res.newGraphData)
graph.value?.fromJSON(graphJson.value.cells)
//首次打开弹窗,默认打开一个工序的数据
//currentStartNode.value = graphJson.value.cells[0]
currentNode.value = graphJson.value.cells[0]
// 手动触发点击事件
nodeClick('','','',currentNode.value,'')
}
//获取配置的工序信息
const getConfigProcessRouteNode= async () => {
let res = await orderDayconfigApi.getConfigProcessRouteNode(queryParams)
processData.value=res
}
//获取配置的工序工位
const getConfigProcessWorkstation= async (code:any) => {
queryParams.processCode=code
workstationData.value = await orderDayconfigApi.getConfigProcessWorkstation(queryParams)
}
//获取配置的工序人员
const getConfigProcessWorker= async (code:any) => {
queryParams.processCode=code
workerData.value = await orderDayconfigApi.getConfigProcessWorker(queryParams)
}
//获取配置的工序设备
const getConfigProcessEquipment= async (code:any) => {
queryParams.processCode=code
equipmentData.value = await orderDayconfigApi.getConfigProcessEquipment(queryParams)
}
const nodeClick = (e, x, y, node, view) => {
//console.log(node.id)
getProcessBom(node.id)
getConfigProcessWorkstation(node.id)
getConfigProcessWorker(node.id)
getConfigProcessEquipment(node.id)
processCode.value = node.id
currentNode.value.id=node.id
//console.log(node)
currentNode.value.name=node.attrs.title.text
}
const searchTableRef = ref()
const opensearchTable = (
) => {
//console.log("opensearchTable")
const _searchCondition = {}
// const _searchTableTitle = "工序查询"
// const _searchTableAllSchemas = ProcessSearch.allSchemas
// const _searchTablePage = ProcessApi.getProcessPage
searchTableRef.value.open(
'工序查询',
ProcessSearch.allSchemas,
ProcessApi.getProcessPage,
'process',
'process',
true,
undefined,
undefined,
_searchCondition,
false,
//true
)
}
const publishPlan=()=>{
message.confirm("确认发布当前计划?","question").then(async () => {
//isPublish.value=true
//loading.value = true,
try{formLoading.value=true
doPublishPlan() }finally{
formLoading.value=false;
}
// loading.value = false,
dialogVisible.value = false,
//isPublish.value=false,
emit('close')
}).catch(() => {
message.info("已取消发布")
})
}
const doPublishPlan= ()=>{
let data ={
updateId: detailData.value.id,
status: detailData.value.status,
remark: detailData.value.remark,
planNoMonth: detailData.value.planNoMonth,
planNoDay: detailData.value.planNoDay,
productCode: detailData.value.productCode,
workroomCode: detailData.value.workroomCode,
lineCode: detailData.value.lineCode,
planCount: detailData.value.planCount,
processrouteCode: detailData.value.processrouteCode,
tempProcessroute: detailData.value.tempProcessroute,
standardBom: detailData.value.standardBom,
tempBom: detailData.value.tempBom,
workMode: detailData.value.workMode,
planDate: detailData.value.planDate,
startTime: detailData.value.planDate,
endTime: detailData.value.endTime,
taskMode: detailData.value.taskMode,
batchCode:detailData.value.batchCode,
}
let res = OrderDayApi.publishPlan(data)
res.then(()=>{
message.success("计划发布成功")
}).catch(()=>{
//console.log("---doPublishPlan-- 458--",res.msg)
message.error("计划发布失败!")
})
}
// 弹层确定返回所选数据
const searchTableSuccess = (formField, searchField, val, type, row) => {
nextTick?.(() => {
if (val.length > 0) {
val.forEach(item => {
if (formField === 'team') {
const { username, nickname, groupName, workerMonitor,code} = item;
const existingWorker = workerData.value.find(worker => worker.workerCode === username);
if (!existingWorker) {
let obj={
workerCode: username,
workerName: nickname,
groupName: groupName,
workerMonitor: workerMonitor,
groupCode: code,
planDayCode : detailData.value.planNoDay,
productCode : detailData.value.productCode,
planBatchCode : detailData.value.batchCode,
processCode : processCode.value,
planDayId : detailData.value.id
}
workerData.value.push(obj);
}
}
else if (formField === 'equipment'){
const { deviceCode, deviceName,deviceType, workroomCode, lineCode,deviceGroup} = item;
const existingWorker = equipmentData.value.find(equipment => equipment.equipmentCode === deviceCode);
if (!existingWorker) {
let obj={
equipmentCode: deviceCode,
equipmentName: deviceName,
equipmentType: deviceType,
equipmentGroup: deviceGroup,
equipmentWorkstation: '',
planDayCode : detailData.value.planNoDay,
productCode : detailData.value.productCode,
planBatchCode : detailData.value.batchCode,
processCode : processCode.value,
planDayId : detailData.value.id
}
equipmentData.value.push(obj);
}
}
else if (formField === 'process') {
const { code, name } = item;
const existingProcess = new Set(processData.value.map(e => e.code));
if (!existingProcess.has(code)) {
processData.value.push({ code, name });
}
}
});
}
dialogFormVisibleUser.value = false;
filterFormTeam.value = {
teamGroup: '',
teamName: ''
}
});
};
const deleteNode=(row)=>{
processData.value.splice(processData.value.indexOf(row),1)
graph.value.removeNode(row.code)
}
/*点击查询,筛选班组数据*/
const searchTeamListCommon = async () =>{
if (filterFormTeam.value.teamGroup != ''){
teamParams.value.teamGroup = filterFormTeam.value.teamGroup
}
if (filterFormTeam.value.teamName != ''){
teamParams.value.name = filterFormTeam.value.teamName
}
teamParams.value.pageNo = currentPage.value
var teamList = await getTeamList(teamParams.value);
teamData.value = teamList.list
totalTeam.value = teamList.total
}
/*打开班组弹窗*/
const opensearchTableUser = async (
) => {
currentPage.value = 1
filterFormTeam.value ={
teamGroup: '',
teamName: ''
}
teamParams.value.teamGroup = ''
teamParams.value.name = ''
teamParams.value.pageNo = 1
teamParams.value.workshopCode = detailData.value.workroomCode
teamParams.value.productionLineCode = detailData.value.lineCode
var teamList = await getTeamList(teamParams.value)
teamData.value = teamList.list
totalTeam.value = teamList.total
dialogFormVisibleUser.value = true
}
/*通过班组,打开班组下的人员信息弹窗*/
const handleConfirm = (row)=>{
const _searchCondition = {}
const filters: any[] = []
filters.push({
action: "==",
column: 'available',
value: 'TRUE'
},{
action: "==",
column: 'code',
value: row.code
})
// 参数整理
_searchCondition.isSearch = true
_searchCondition.filters = filters
searchTableRef.value.open(
'添加人员',//弹出层标题
searchUser.allSchemas,
TeamApi.geTeamUserByCode,
'team',
'team',
true,//是否支持多选
undefined,
undefined,
_searchCondition
)
}
/*选择设备弹窗*/
const opensearchTableEquipment = async (
) => {
const _searchCondition = {}
const filters: any[] = []
filters.push({
action: "==",
column: 'workroomCode',
value: detailData.value.workroomCode
},{
action: "==",
column: 'lineCode',
value: detailData.value.lineCode
})
// 参数整理
// _searchCondition.isSearch = true
// _searchCondition.filters = filters
searchTableRef.value.open(
'添加设备',//弹出层标题
DeviceInfo.allSchemas,
orderDayconfigApi.getDeviceInfoPage,
'equipment',
'equipment',
true,//是否支持多选
undefined,
undefined,
_searchCondition
)
}
/*设备保存接口*/
const saveEquipment = async () =>{
await orderDayconfigApi.saveEquipment(equipmentData.value)
//console.log(equipmentData.value)
message.success("设备配置成功!")
}
/*删除设备标签*/
const deleteEquipment=(row)=>{
equipmentData.value.splice(equipmentData.value.indexOf(row),1)
}
/*删除选择的班组人员*/
const deleteUser=(row)=>{
workerData.value.splice(workerData.value.indexOf(row),1)
}
/*班组人员保存接口*/
const saveUser = async () =>{
await orderDayconfigApi.saveWorker(workerData.value)
message.success("人员配置成功!")
}
/*分页查询班组信息*/
const getTeamList = async (params:any) => {
return TeamApi.getTeamPage(params)
}
const handleCurrentChangeM=(value: number)=>{
let index=(value-1)*page.value.size
page.value.current=value
showMaterialsData.value=materialsData.value.slice(index,index+page.value.size)
}
const handlePrevClickM=(value: number)=>{
page.value.current=value-1
if(page.value.current==0) {
page.value.current=1
}
}
const handleNextClickM=(value: number)=>{
page.value.current=value+1
if(page.value.current>page.value.total/page.value.size) {
page.value.current=page.value.total/page.value.size -1
}
}
defineOptions({ name: 'SechledDetail' })
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
// 传递给父类
const emit = defineEmits([
'close'
])
</script>
<style lang="scss">
.el-drawer__body {
background: #f5f5f5 !important;
}
::v-deep(.label-class-name) {
color: #dedede;
}
</style>