<!--
|
* @Description: 工单管理页面
|
* @Author: Ben Lin
|
* @version:
|
* @Date: 2024-05-25 00:27:00
|
* @LastEditors: Ben Lin
|
* @LastEditTime: 2024-06-24 22:58:16
|
-->
|
<template>
|
<div>
|
<BasicTable @register="registerTable">
|
<template #toolbar>
|
<a-button type="primary" @click="addWo" preIcon="add_02|svg"> 新增 </a-button>
|
<a-button ghost color="success" @click="ExcelToDb" preIcon="excel-import|svg">
|
导入
|
</a-button>
|
</template>
|
<template #form-add="{ field }">
|
<a-button
|
v-if="field"
|
class="mt-1 ml-1"
|
size="small"
|
@click="handleSelectItem"
|
preIcon="search|svg"
|
/>
|
<GeneralModal @register="registerItemAdd" @success="handleItemSuccess" />
|
</template>
|
<template #action="{ record }">
|
<TableAction
|
:actions="[
|
{
|
icon: 'clarity:note-edit-line',
|
tooltip: '修改',
|
onClick: handleEdit.bind(null, record),
|
},
|
{
|
icon: 'ant-design:delete-outlined',
|
color: 'error',
|
tooltip: '删除',
|
popConfirm: {
|
title: '是否确认删除?',
|
placement: 'left',
|
confirm: handleDelete.bind(null, record),
|
},
|
},
|
{
|
icon: 'config|svg',
|
tooltip: '配置工艺',
|
onClick: handleConfig.bind(null, record),
|
},
|
{
|
icon: 'release|svg',
|
tooltip: '下发',
|
onClick: handleRelease.bind(null, record),
|
},
|
{
|
icon: 'unrelease|svg',
|
tooltip: '取消下发',
|
onClick: handleUnRelease.bind(null, record),
|
},
|
{
|
icon: 'suspend-blue|svg',
|
tooltip: '暂停',
|
onClick: handlePause.bind(null, record),
|
},
|
]"
|
/>
|
</template>
|
</BasicTable>
|
<Loading :loading="compState.loading" :tip="compState.tip" />
|
<WoDrawer @register="registerDrawer" @success="handleSuccess" />
|
<WoModal @register="registerWo" @success="handleSuccess" :title="title" :mtitle="mtitle" />
|
<!-- 自定义模态框,可以自定义多表单 -->
|
<CustModal
|
@register="registerCust"
|
@success="custSuccess"
|
:type="cType"
|
:detailSlots="dtlSlots"
|
>
|
<!-- 用插槽自定义多表单 -->
|
<template #[item.name] v-for="item in dtlSlots" :key="item.name">
|
<BasicForm @register="useFormData[item.name][0]" v-if="useFormData[item.name]">
|
<!-- 用插槽自定义弹出选择框 -->
|
<template #[name]="{ field }" v-for="name in item.slots" :key="name">
|
<a-button
|
class="mt-1 ml-1"
|
size="small"
|
@click="handleCustClick(field)"
|
:preIcon="item.preIcons[name]"
|
/>
|
<GeneralModal
|
@register="useModalData[name][0]"
|
@success="(d, u) => handleEntSuccess(d, u, item.name)"
|
/>
|
</template>
|
</BasicForm>
|
<!-- 自定义内容 -->
|
<div style="height: 200px" id="lfContainer" v-if="isCustEl[item.name]"></div>
|
</template>
|
</CustModal>
|
<RouteViewModal @register="registerRv" @success="RvItemSuccess" />
|
</div>
|
</template>
|
<script lang="ts" setup>
|
import { reactive, unref, h, onMounted, ref, nextTick, Ref } from 'vue';
|
import { Steps, Step, Layout, LayoutContent } from 'ant-design-vue';
|
import { BasicTable, useTable, TableAction } from '/@/components/Table';
|
import { BasicForm, FormSchema, FormActionType, useForm } from '/@/components/Form/index';
|
import WoDrawer from './WoDrawer.vue';
|
import WoModal from './WoModal.vue';
|
import GeneralModal from '/@/views/components/GeneralModal.vue';
|
import RouteViewModal from '/@/views/components/RouteViewModal.vue';
|
import CustModal from '/@/views/components/CustModal.vue';
|
import { useDrawer } from '/@/components/Drawer';
|
import { columns, searchFormSchema } from './biz_mes_wo.data';
|
import { DeleteMesWo } from '/@/api/tigerapi/mes/wo';
|
import { Loading } from '/@/components/Loading';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useModal } from '/@/components/Modal';
|
import { SaveEntity, getListByPage } from '/@/api/tigerapi/system';
|
import { GetSelectSuccess, OpenSelectItem, getFormSchema } from '/@/views/components/data';
|
import LogicFlow from '@logicflow/core';
|
import { getRouteData } from '/@/api/tigerapi/mes/router';
|
import actionRect from '/@/components/FlowChart/src/actionRect';
|
import TestNode from '/@/components/FlowChart/src/TestNode';
|
import CollectNode from '/@/components/FlowChart/src/CollectNode';
|
import AssemblyNode from '/@/components/FlowChart/src/AssemblyNode';
|
import PackingNode from '/@/components/FlowChart/src/PackingNode';
|
import RepairNode from '/@/components/FlowChart/src/RepairNode';
|
import customEdge from '/@/components/FlowChart/src/customEdge';
|
import { BpmnElement } from '@logicflow/extension';
|
|
const { t } = useI18n();
|
const ASteps = Steps;
|
const AStep = Step;
|
const cType = ref('');
|
const title = ref('工单导入');
|
const mtitle = ref('工单列表');
|
const dtlSlots = ref([] as any[]);
|
const selectVals = ref({});
|
const { createMessage, createErrorModal } = useMessage();
|
const [registerDrawer, { openDrawer }] = useDrawer();
|
const compState = reactive({
|
absolute: false,
|
loading: false,
|
tip: '加载中...',
|
});
|
const lfInstance = ref(null) as Ref<LogicFlow | null>;
|
const [registerRv, { openModal: openRvModal }] = useModal();
|
const [registerWo, { openModal: openWoModal }] = useModal();
|
const [registerItemAdd, { openModal: openItemModal }] = useModal();
|
const [registerCust, { openModal: openCustModal, closeModal }] = useModal();
|
const [registerTable, { getForm, reload }] = useTable({
|
title: '工单信息',
|
api: getListByPage,
|
columns,
|
formConfig: {
|
labelWidth: 120,
|
schemas: searchFormSchema,
|
},
|
actionColumn: {
|
width: 220,
|
title: '操作',
|
dataIndex: 'action',
|
slots: { customRender: 'action' },
|
fixed: 'right', //undefined,
|
},
|
ellipsis: true,
|
useSearchForm: true,
|
showTableSetting: true,
|
bordered: true,
|
showIndexColumn: false,
|
});
|
const routeData = ref({
|
nodes: [],
|
edges: [],
|
});
|
const formSchema = ref([] as FormSchema[]);
|
const woSchema = ref([] as FormSchema[]);
|
const prodSchema = ref([] as FormSchema[]);
|
const isCustEl = ref({
|
forminfo: false,
|
woinfo: false,
|
prodinfo: false,
|
rotinfo: true,
|
});
|
//表单中插槽渲染按钮打开模态框useModal方法
|
const useModalData = ref({
|
add: useModal(),
|
set: useModal(),
|
addRot: useModal(),
|
setRot: useModal(),
|
});
|
//自定义多表单实例
|
const useFormData = ref({
|
forminfo: useForm({
|
labelWidth: 120,
|
schemas: formSchema,
|
actionColOptions: {
|
span: 24,
|
},
|
showActionButtonGroup: false,
|
}),
|
woinfo: useForm({
|
labelWidth: 120,
|
schemas: woSchema,
|
actionColOptions: {
|
span: 24,
|
},
|
showActionButtonGroup: false,
|
}),
|
prodinfo: useForm({
|
labelWidth: 120,
|
schemas: prodSchema,
|
actionColOptions: {
|
span: 24,
|
},
|
showActionButtonGroup: false,
|
}),
|
// rotinfo: useForm({
|
// labelWidth: 120,
|
// schemas: rotSchema,
|
// actionColOptions: {
|
// span: 24,
|
// },
|
// showActionButtonGroup: false,
|
// }),
|
});
|
|
onMounted(async () => {});
|
|
//新增
|
function addWo() {
|
openDrawer(true, {
|
isUpdate: false,
|
});
|
}
|
//编辑
|
function handleEdit(record: any) {
|
openDrawer(true, {
|
isUpdate: true,
|
record,
|
});
|
}
|
function handleSuccess() {
|
reload();
|
}
|
//导入
|
function ExcelToDb() {
|
openWoModal(true, {
|
data: 'content',
|
info: 'Info',
|
});
|
}
|
//配置工艺
|
function handleConfig(record: Recordable) {
|
cType.value = 'BIZ_MES_WO_Config';
|
dtlSlots.value = [
|
{ name: 'woinfo', slots: [], preIcons: {}, title: '工单信息' },
|
{
|
name: 'prodinfo',
|
slots: ['addRot', 'setRot'],
|
preIcons: { addRot: 'search|svg', setRot: 'config|svg' },
|
title: '产品信息',
|
},
|
{ name: 'rotinfo', slots: ['add'], preIcons: { add: 'search|svg' }, title: '工艺信息' },
|
];
|
woSchema.value = getFormSchema('woinfo');
|
prodSchema.value = getFormSchema('prodinfo');
|
// rotSchema.value = getFormSchema('rotinfo');
|
//工艺路线渲染图初始化
|
if (lfInstance.value != null) {
|
routeData.value = {
|
nodes: [],
|
edges: [],
|
};
|
const lf = unref(lfInstance)!;
|
lf.render({});
|
}
|
selectVals.value['ROUTE_CODE'] = record.ROUTE_CODE;
|
openCustModal(true, {
|
isUpdate: true,
|
ctype: cType,
|
title: '工艺配置',
|
width: '1000px',
|
formEl: useFormData.value, //如果是多个表单,增加多个插槽
|
formElName: ['woinfo', 'prodinfo', 'rotinfo'], //表单插槽名称,支持多个表单
|
RowKey: '',
|
fnName: { BIZ_MES_WO_Config: 'SaveCofig' }, //保存方法名
|
initFnName: { BIZ_MES_WO_Config: 'initRoute' }, //初始化方法名
|
isCustEl: isCustEl.value,
|
others: routeData.value,
|
values: record, //表单记录
|
});
|
}
|
|
/**
|
* @description: 下发
|
* @param {*} record
|
* @return {*}
|
*/
|
function handleRelease(record: Recordable) {
|
if (record.STATUS == 2) {
|
createErrorModal({
|
title: t('警告'),
|
content: t('工单已经下发,不能再下发!'),
|
getContainer: () => document.body,
|
});
|
return;
|
}
|
cType.value = 'BIZ_MES_WO';
|
dtlSlots.value = [
|
{
|
name: 'forminfo',
|
slots: ['add', 'set'],
|
preIcons: { add: 'search|svg', set: 'config|svg' }, //如果是多个表单,增加多个插槽。slots是弹出框按钮的插槽,preIcons是插槽对应的按钮图标
|
title: '下发配置',
|
},
|
];
|
formSchema.value = getFormSchema(cType.value);
|
openCustModal(true, {
|
isUpdate: true, //是否更新操作
|
ctype: cType, //是哪个页面
|
title: '工单下发', //标题
|
width: '900px', //弹出框宽度
|
formEl: useFormData.value,
|
formElName: ['forminfo'], //表单插槽名称
|
RowKeys: { add: 'ROUTE_CODE', set: 'ROUTE_CODE' }, //插槽的弹出框选择的code
|
fnName: { BIZ_MES_WO: 'SaveWoBatch' }, //保存方法名
|
initFnName: {}, //初始化方法名
|
isCustEl: isCustEl.value,
|
values: record, //表单记录
|
});
|
}
|
|
/**
|
* @description: 取消下发
|
* @param {*} record
|
* @return {*}
|
*/
|
function handleUnRelease(record: Recordable) {
|
if (record.STATUS == 0) {
|
createErrorModal({
|
title: t('警告'),
|
content: t('工单是初始化状态,不能取消下发!'),
|
getContainer: () => document.body,
|
});
|
return;
|
}
|
record.STATUS = 0;
|
SaveEntity(record, true, 'BIZ_MES_WO').then((action) => {
|
if (action.IsSuccessed) {
|
createMessage.success(t('已取消下发'));
|
reload();
|
} else {
|
createMessage.success(t('取消下发操作失败'));
|
}
|
});
|
}
|
//暂停
|
function handlePause(record: Recordable) {
|
if (record.STATUS == 0) {
|
createErrorModal({
|
title: t('警告'),
|
content: t('工单是初始化状态,不能暂停!'),
|
getContainer: () => document.body,
|
});
|
return;
|
}
|
if (record.STATUS == 5) {
|
createErrorModal({
|
title: t('警告'),
|
content: t('工单是完成状态,不能暂停!'),
|
getContainer: () => document.body,
|
});
|
return;
|
}
|
record.STATUS = 4;
|
SaveEntity(record, true, 'BIZ_MES_WO').then((action) => {
|
if (action.IsSuccessed) {
|
createMessage.success(t('已暂停'));
|
reload();
|
} else {
|
createMessage.success(t('暂停操作失败'));
|
}
|
});
|
}
|
|
/**
|
* @description: 删除
|
* @param {*} record
|
* @return {*}
|
*/
|
function handleDelete(record: Recordable) {
|
DeleteMesWo(record.ID).then((action) => {
|
if (action.IsSuccessed) {
|
createMessage.success(t('已删除'));
|
reload();
|
} else {
|
createMessage.success(t('删除操作失败'));
|
}
|
});
|
}
|
|
/**
|
* @description: 弹出框确定返回
|
* @param {*} d
|
* @return {*}
|
*/
|
function custSuccess(d) {
|
reload();
|
}
|
|
/**
|
* @description: 点击打开物料列表框
|
* @return {*}
|
*/
|
function handleSelectItem() {
|
openItemModal(true, {
|
title: '物料列表',
|
schemas: [
|
{
|
field: 'ITEM_CODE',
|
component: 'Input',
|
label: '物料编码',
|
colProps: {
|
span: 12,
|
},
|
},
|
],
|
ItemColumns: [
|
{
|
title: t('物料编码'),
|
dataIndex: 'ITEM_CODE',
|
resizable: true,
|
sorter: true,
|
width: 200,
|
},
|
{
|
title: t('物料名称'),
|
dataIndex: 'ITEM_NAME',
|
resizable: true,
|
sorter: true,
|
width: 180,
|
},
|
],
|
tableName: 'BAS_ITEM',
|
rowKey: 'ITEM_CODE',
|
searchInfo: {TABLE_NAME: 'BAS_ITEM'}
|
});
|
}
|
|
/**
|
* @description: 弹出选择物料框返回成功方法
|
* @param {*} d
|
* @param {*} u
|
* @return {*}
|
*/
|
function handleItemSuccess(d, u) {
|
getForm().setFieldsValue({
|
ITEM_CODE: d.values['val'],
|
});
|
}
|
|
/**
|
* @description: 各表单内弹出选择框选择成功后方法
|
* @param {*} d
|
* @param {*} u
|
* @param {*} item
|
* @return {*}
|
*/
|
function handleEntSuccess(d, u, item) {
|
var values = GetSelectSuccess(d, u, cType.value);
|
selectVals.value = values; //保存弹出框选择的结果
|
let _val = {};
|
_val[d.returnFieldName] = values[d.returnFieldName];
|
useFormData.value[item][1].setFieldsValue(_val);
|
if (d.returnFieldName == 'ROUTE_CODE' && cType.value == 'BIZ_MES_WO_Config') {
|
routeData.value = {
|
nodes: [],
|
edges: [],
|
};
|
init(selectVals.value['ROUTE_CODE']);
|
}
|
}
|
|
/**
|
* @description: 弹出选择框
|
* @param {*} item
|
* @return {*}
|
*/
|
function handleCustClick(item) {
|
//打开自定义模态框
|
OpenSelectItem(
|
useModalData.value[item][1].openModal, //带入openModal方法
|
cType.value,
|
item,
|
[openRvModal],
|
selectVals.value['ROUTE_CODE'],
|
); //[openRvModal], selectVals.value['ID']这是自定义参数,按实际需求
|
}
|
function RvItemSuccess(d, u) {}
|
|
async function init(rotId) {
|
LogicFlow.use(BpmnElement);
|
lfInstance.value = new LogicFlow({
|
container: document.querySelector('#lfContainer'),
|
edgeGenerator: (sourceNode) => {
|
// console.log('a');
|
// 起始节点类型 rect 时使用 自定义的边 custom-edge
|
if (sourceNode.properties.isReturn) return 'custom-edge';
|
// if (sourceNode.type === 'rect') return 'custom-edge';
|
// return 'custom-edge';
|
},
|
});
|
const lf = unref(lfInstance)!;
|
// lf?.setDefaultEdgeType('line');
|
lf.register(customEdge);
|
lf.register(actionRect);
|
lf.register(TestNode);
|
lf.register(CollectNode);
|
lf.register(AssemblyNode);
|
lf.register(PackingNode);
|
lf.register(RepairNode);
|
lf.render({});
|
//通过工艺路线ID获取图形数据,并渲染
|
var _data = await getRouteData(rotId);
|
console.log('组件已挂载', _data);
|
//工艺路线全信息,包括Node、Edge和Act
|
// routeConfig.routeData = _data.Data;
|
if (_data.Data != null) {
|
//工艺路线主信息
|
var currRoute = _data.Data.route;
|
_data.Data.nodes.forEach((n) => {
|
n.node.properties = JSON.parse(n.node.properties);
|
routeData.value.nodes.push(n.node);
|
});
|
console.log('111', routeData.value);
|
_data.Data.edges.forEach((e) => {
|
e.edge.properties = JSON.parse(e.edge.properties);
|
routeData.value.edges.push(e.edge);
|
});
|
_data.Data.acts.forEach((act) => {
|
act.node.properties = JSON.parse(act.node.properties);
|
routeData.value.nodes.push(act.node);
|
});
|
console.log('init', unref(lf).getGraphData(), JSON.parse(JSON.stringify(routeData.value)));
|
lf.render(routeData.value);
|
// lf.graphModel.resize(500, 400);
|
lf.graphModel.fitView();
|
lf.graphModel.translateCenter();
|
}
|
}
|
</script>
|