Ben Lin
2024-05-01 532e24e6c347c56757124f627945b73c5c637ff5
src/views/tigerprojects/mes/eng/route/index.vue
@@ -1,48 +1,47 @@
<template>
  <PageWrapper title="工艺流程图" content="根据生产工艺设计工艺流程" contentFullHeight fixedHeight>
    <Layout class="h-full">
      <LayoutContent>
        <FlowChart :data="demoData" @save-data="handleSave" @add-lf="handleAddlf" />
      <LayoutContent :style="{ overflow: 'initial' }">
        <FlowChart
          :data="routeData"
          @save-data="handleSave"
          @add-lf="handleAddlf"
          @select-node="handleSelect"
          @click-blank="clickBlank"
          @init="init"
        />
      </LayoutContent>
      <LayoutSider
        :class="`right`"
        collapsible
        :reverseArrow="true"
        collapsedWidth="0"
        width="450"
        width="300"
        style="background: #fafafa; border-left: 1px solid #d9d9d9; padding: 10px"
        :zeroWidthTriggerStyle="{ 'margin-top': '-70px', 'background-color': 'gray' }"
      >
        <PropsPanel ref="propsPanel" :activeKey="activeKey">
          <template v-for="item of schemas" #[`${item.component}Props`]="data">
        <PropsPanel ref="propsPanel" :activeKey="routeConfig.activeKey">
          <!-- <template v-for="item of formConfig.schemas" #[`${item.component}Props`]="data">
            <slot
              :name="`${item.component}Props`"
              v-bind="{ formItem: data, props: data.componentProps }"
            ></slot>
          </template>
          </template> -->
        </PropsPanel>
        <!-- <BasicForm
          autoFocusFirstItem
          :labelWidth="120"
          :schemas="schemas"
          :actionColOptions="{ span: 24 }"
          :submitButtonOptions="{ text: '确定' }"
          @submit="handleSubmit"
          @reset="handleReset"
      /> -->
      </LayoutSider>
    </Layout>
    <RouteDrawer @register="registerDrawer" @success="handleSuccess" />
    <RouteModal @register="registerModal" @success="modalSuccess" />
  </PageWrapper>
</template>
<script lang="ts" setup>
  import { FlowChart } from '/@/components/FlowChart';
  import { PageWrapper } from '/@/components/Page';
  import { BasicForm, FormSchema } from '/@/components/Form/index';
  import { getOperAllList } from '/@/api/tigerapi/mes/oper';
  import { SaveRouteData } from '/@/api/tigerapi/mes/router';
  import { ref, unref } from 'vue';
  import { SaveRouteData, getRouteData } from '/@/api/tigerapi/mes/router';
  import { useModal } from '/@/components/Modal';
  import RouteModal from './RouteModal.vue';
  import { onMounted, ref, unref, Ref, provide, reactive, nextTick } from 'vue';
  import { Layout, LayoutContent, LayoutSider } from 'ant-design-vue';
  import {
    RouteData,
@@ -50,190 +49,48 @@
    edge,
    MES_ROUTE_NODE,
    MES_ROUTE_EDGE,
    MES_ROUTE_NODE_ACT,
    MES_ROUTE,
  } from '/@/api/tigerapi/model/router';
  import { useUserStore } from '/@/store/modules/user';
  import { buildUUID } from '/@/utils/uuid';
  import RouteDrawer from './RouteDrawer.vue';
  import { useDrawer } from '/@/components/Drawer';
  import PropsPanel from './components/PropsPanel.vue';
  import { IRouteConfig } from './typings/v-form-component';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { isNullOrEmpty } from '/@/utils/is';
  import { useRoute } from 'vue-router';
  import { useTabs } from '/@/hooks/web/useTabs';
  const [registerDrawer, { openDrawer }] = useDrawer();
  const isRute = (type: string) => type === '0';
  const isOper = (type: string) => type === '1';
  const activeKey = ref(1);
  const schemas: FormSchema[] = [
    {
      field: 'func_type',
      label: '属性页',
      component: 'RadioButtonGroup',
      defaultValue: '0',
      componentProps: {
        options: [
          { label: '工艺流程', value: '0' },
          { label: '工序', value: '1' },
        ],
      },
      colProps: { lg: 24, md: 24 },
    },
    {
      field: 'OPER_CODE',
      component: 'ApiSelect',
      label: '选择工序',
      componentProps: {
        api: getOperAllList,
        // params: {
        //   id: 1,
        // },
        resultField: 'items',
        labelField: 'OPER_NAME',
        valueField: 'OPER_CODE',
        // not request untill to select
        immediate: false,
        onChange: (e) => {
          console.log('selected:', e);
        },
        // atfer request callback
        onOptionsChange: (options) => {
          console.log('get options', options.length, options);
        },
      },
      ifShow: ({ values }) => isOper(values.func_type),
    },
    {
      field: 'field2',
      component: 'Input',
      label: '工序类型',
      // componentProps:{},
      // can func
      componentProps: ({ schema, formModel }) => {
        console.log('form:', schema);
        console.log('formModel:', formModel);
        return {
          placeholder: '测试',
          onChange: (e: any) => {
            console.log(e);
          },
        };
      },
      renderComponentContent: () => {
        return {
          prefix: () => '工序',
          suffix: () => '类型',
        };
      },
      ifShow: ({ values }) => isOper(values.func_type),
    },
    {
      field: 'field3',
      component: 'Select',
      label: '工序行为',
      componentProps: {
        options: [
          {
            label: '存储过程',
            value: '1',
            key: '1',
          },
          {
            label: '条码规则',
            value: '2',
            key: '2',
          },
          {
            label: '行为一',
            value: '3',
            key: '3',
          },
          {
            label: '行为二',
            value: '4',
            key: '4',
          },
          {
            label: '行为三',
            value: '5',
            key: '5',
          },
        ],
      },
      ifShow: ({ values }) => isOper(values.func_type),
    },
    {
      field: 'field4',
      component: 'Switch',
      label: '是否计算直通率',
      colProps: {
        span: 16,
      },
      labelWidth: 200,
      ifShow: ({ values }) => isOper(values.func_type),
    },
    {
      field: 'field5',
      component: 'Switch',
      label: '是否可跳站',
      colProps: {
        span: 16,
      },
      labelWidth: 200,
      ifShow: ({ values }) => isOper(values.func_type),
    },
    {
      field: 'ROT_CODE',
      label: '工艺路线编码',
      required: true,
      component: 'Input',
      colProps: { span: 16 },
      ifShow: ({ values }) => isRute(values.func_type),
    },
    {
      field: 'ROT_NAME',
      label: '工艺路线名称',
      required: true,
      component: 'Input',
      colProps: { span: 16 },
      ifShow: ({ values }) => isRute(values.func_type),
    },
    {
      field: 'ROT_TYPE',
      label: '工艺路线类型',
      required: true,
      component: 'Input',
      colProps: { span: 16 },
      ifShow: ({ values }) => isRute(values.func_type),
    },
    {
      field: 'ROT_VER',
      label: '工艺路线版本',
      required: true,
      component: 'Input',
      colProps: { span: 16 },
      ifShow: ({ values }) => isRute(values.func_type),
    },
    {
      field: 'IS_ACTIVE',
      label: '是否启用',
      required: true,
      component: 'Select',
      colProps: { span: 16 },
      componentProps: {
        options: [
          {
            label: '是',
            value: 'Y',
            key: 'Y',
          },
          {
            label: '否',
            value: 'N',
            key: 'N',
          },
        ],
      },
      ifShow: ({ values }) => isRute(values.func_type),
    },
  ];
  const demoData = ref({});
  const [registerModal, { openModal }] = useModal();
  const { t } = useI18n();
  const route = useRoute();
  const { setTitle } = useTabs();
  const { notification, createErrorModal } = useMessage();
  const routeConfig = reactive({
    // 表单配置
    schemas: [],
    layout: 'horizontal',
    labelLayout: 'flex',
    labelWidth: 100,
    labelCol: {},
    wrapperCol: {},
    currentItem: {} as MES_ROUTE_NODE,
    activeKey: 1,
  } as IRouteConfig);
  const currRoute = ref({} as MES_ROUTE);
  const routeData = ref({
    nodes: [],
    edges: [],
  });
  provide<Ref<IRouteConfig>>('routeConfig', routeConfig);
  provide<Ref<MES_ROUTE>>('mesRoute', currRoute);
  const selectnode = ref({} as node);
  const currRotId = ref(route.params?.id);
  console.log(currRotId.value);
  // const demoData1 = ref({
  //   nodes: [
  //     {
@@ -353,94 +210,239 @@
  //     },
  //   ],
  // });
  function handleReset() {}
  function handleSubmit(_values: any) {
    try {
    } catch {}
  if (!isNullOrEmpty(currRotId.value)) {
    setTitle('设计:工艺路线' + currRotId.value);
  }
  async function init(lf) {
    //通过工艺路线ID获取图形数据,并渲染
    var _data = await getRouteData(currRotId.value);
    console.log('组件已挂载', _data);
    currRoute.value = _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)));
    unref(lf).render(routeData.value);
  }
  async function handleSave(lf) {
    console.log('handleSave', unref(lf).getGraphData().nodes[0]);
    var _routeData: RouteData = {
      route: {
        ID: buildUUID(),
        CREATE_TIME: new Date(),
        CREATE_USER: useUserStore().getUserInfo.userId as string,
        UPDATE_TIME: new Date(),
        UPDATE_USER: useUserStore().getUserInfo.userId as string,
        GHOST_ROW: false,
        ROT_CODE: 'R001',
        ROT_NAME: 'R001',
        ROT_TYPE: '',
        ROT_VER: '01',
        IS_ACTIVE: 'Y',
        REMARK: 'R001',
      },
      nodes: [],
      edges: [],
    };
    var _nodes = unref(lf).getGraphData().nodes as node[];
    var _edges = unref(lf).getGraphData().edges as edge[];
    _nodes.forEach((n) => {
      var node: MES_ROUTE_NODE = {
        ID: '',
        CREATE_TIME: _routeData.route.CREATE_TIME,
        CREATE_USER: useUserStore().getUserInfo.userId as string,
        UPDATE_TIME: _routeData.route.UPDATE_TIME,
        UPDATE_USER: useUserStore().getUserInfo.userId as string,
        GHOST_ROW: false,
        NODE_CODE: 'N001',
        NODE_NAME: 'N001',
        ROT_CODE: _routeData.route.ROT_CODE,
        SEGMENT: '',
        OPER_CODE: '',
        GPH_TYPE: n.type,
        GPH_X: n.x,
        GPH_Y: n.y,
        GPH_PROP: '',
        GPH_TEXT: n.text.value,
        IS_ACTIVE: 'Y',
        IS_CALC_FPY: 'N',
        CAN_SKIP: 'N',
        REMARK: '',
    if (isNullOrEmpty(currRoute.value.ROT_CODE)) {
      createErrorModal({
        title: t('未选择'),
        content: t('未选择工艺路线或者新增工艺路线'),
        getContainer: () => document.body,
      });
    } else {
      var _routeData: RouteData = {
        route: {
          ID: currRoute.value.ID,
          CREATE_TIME: new Date(),
          CREATE_USER: useUserStore().getUserInfo.userId as string,
          UPDATE_TIME: new Date(),
          UPDATE_USER: useUserStore().getUserInfo.userId as string,
          GHOST_ROW: false,
          ROT_CODE: currRoute.value.ROT_CODE,
          ROT_NAME: currRoute.value.ROT_NAME,
          ROT_TYPE: currRoute.value.ROT_TYPE,
          ROT_VER: currRoute.value.ROT_VER,
          IS_ACTIVE: currRoute.value.IS_ACTIVE,
          REMARK: currRoute.value.REMARK,
          AUTH_ORG: '',
          AUTH_PROD: '',
          AUTH_WH: '',
        },
        nodes: [],
        edges: [],
        acts: [],
      };
      _routeData.nodes.push(node);
    });
    _edges.forEach((e) => {
      var edge: MES_ROUTE_EDGE = {
        ID: '',
        CREATE_TIME: _routeData.route.CREATE_TIME,
        CREATE_USER: useUserStore().getUserInfo.userId as string,
        UPDATE_TIME: _routeData.route.UPDATE_TIME,
        UPDATE_USER: useUserStore().getUserInfo.userId as string,
        GHOST_ROW: false,
        EDGE_CODE: 'E001',
        EDGE_NAME: 'E001',
        ROT_CODE: _routeData.route.ROT_CODE,
        SRC_NODE: e.sourceNodeId,
        TGT_NODE: e.targetNodeId,
        GPH_TYPE: e.type,
        GPH_SRC_X: e.startPoint.x,
        GPH_SRC_Y: e.startPoint.y,
        GPH_TGT_X: e.endPoint.x,
        GPH_TGT_Y: e.endPoint.y,
        GPH_PROP: '',
        GPH_POTS: JSON.stringify(e.pointsList),
        REMARK: '',
      };
      _routeData.edges.push(edge);
    });
    await SaveRouteData(_routeData);
      var _nodes = unref(lf).getGraphData().nodes as node[];
      var _edges = unref(lf).getGraphData().edges as edge[];
      var _num = 1;
      _nodes.forEach((n) => {
        if (n.properties.operType && n.properties.operType == 'Action') {
          var act: MES_ROUTE_NODE_ACT = {
            ID: n.id,
            CREATE_TIME: _routeData.route.CREATE_TIME,
            CREATE_USER: useUserStore().getUserInfo.userId as string,
            UPDATE_TIME: _routeData.route.UPDATE_TIME,
            UPDATE_USER: useUserStore().getUserInfo.userId as string,
            GHOST_ROW: false,
            ROT_ID: _routeData.route.ID,
            GPH_TYPE: n.type,
            GPH_X: n.x,
            GPH_Y: n.y,
            GPH_PROP: JSON.stringify(n.properties),
            GPH_TEXT: n.text.value,
            REMARK: '',
            AUTH_ORG: '',
            AUTH_PROD: '',
            AUTH_WH: '',
            OPTION_1: '',
            OPTION_2: '',
            OPTION_3: '',
            OPTION_4: '',
            OPTION_5: '',
            ACT_NAME: `${_routeData.route.ROT_CODE}_${n.text.value}_${_num}`,
            NODE_ID: '',
            ACT_TYPE: 0,
            DO_TYPE: 0,
            DO_METHOD: '',
            DO_IF_PASS: '',
            DO_IF_FAIL: '',
            RULE_CODE: '',
            ITEM_CODE: '',
            PROD_CODE: '',
            TEST_CODE: '',
            SAPL_CODE: '',
            LABEL_CODE: '',
          };
          var pnode = [n];
          while (pnode[0].properties.operType == 'Action') {
            pnode = unref(lf).getNodeIncomingNode(pnode[0].id);
            if (pnode[0].properties.operType != 'Action') {
              act.NODE_ID = pnode[0].id;
              break;
            }
          }
          _routeData.acts.push(act);
        } else {
          var node: MES_ROUTE_NODE = {
            ID: n.id,
            CREATE_TIME: _routeData.route.CREATE_TIME,
            CREATE_USER: useUserStore().getUserInfo.userId as string,
            UPDATE_TIME: _routeData.route.UPDATE_TIME,
            UPDATE_USER: useUserStore().getUserInfo.userId as string,
            GHOST_ROW: false,
            NODE_NAME: `${_routeData.route.ROT_CODE}_${n.text.value}_${_num}`,
            ROT_ID: _routeData.route.ID,
            SEGMENT: '',
            OPER_CODE: '',
            GPH_TYPE: n.type,
            GPH_X: n.x,
            GPH_Y: n.y,
            GPH_PROP: JSON.stringify(n.properties),
            GPH_TEXT: n.text.value,
            IS_ACTIVE: 'Y',
            IS_CALC_FPY: 'N',
            CAN_SKIP: 'N',
            REMARK: '',
            AUTH_ORG: '',
            AUTH_PROD: '',
            AUTH_WH: '',
            IS_FIRST_NODE: 'N',
            IS_INPUT: '',
            IS_OUTPUT: '',
            OPTION_1: '',
            OPTION_2: '',
            OPTION_3: '',
            OPTION_4: '',
            OPTION_5: '',
          };
          if (unref(lf).getNodeIncomingNode(n.id).length == 0) {
            node.IS_FIRST_NODE = 'Y';
          }
          _routeData.nodes.push(node);
        }
        _num++;
      });
      _edges.forEach((e) => {
        var edge: MES_ROUTE_EDGE = {
          ID: e.id,
          CREATE_TIME: _routeData.route.CREATE_TIME,
          CREATE_USER: useUserStore().getUserInfo.userId as string,
          UPDATE_TIME: _routeData.route.UPDATE_TIME,
          UPDATE_USER: useUserStore().getUserInfo.userId as string,
          GHOST_ROW: false,
          EDGE_NAME: `${_routeData.route.ROT_CODE}_${e.id}`,
          ROT_ID: _routeData.route.ID,
          SRC_NODE: e.sourceNodeId,
          TGT_NODE: e.targetNodeId,
          GPH_TYPE: e.type,
          GPH_SRC_X: e.startPoint.x,
          GPH_SRC_Y: e.startPoint.y,
          GPH_TGT_X: e.endPoint.x,
          GPH_TGT_Y: e.endPoint.y,
          GPH_PROP: JSON.stringify(e.properties),
          GPH_POTS: JSON.stringify(e.pointsList),
          REMARK: '',
          AUTH_ORG: '',
          AUTH_PROD: '',
          AUTH_WH: '',
          EDGE_TYPE: 0,
          OPTION_1: '',
          OPTION_2: '',
          OPTION_3: '',
          OPTION_4: '',
          OPTION_5: '',
        };
        _routeData.edges.push(edge);
      });
      await SaveRouteData(_routeData);
    }
  }
  async function handleAddlf(lf) {
    openDrawer(true, {
    // openDrawer(true, {
    //   isUpdate: false,
    //   lf: lf,
    // });
    openModal(true, {
      isUpdate: false,
      lf: lf,
    });
  }
  function handleSelect(data) {
    selectnode.value = data.data;
    routeConfig.currentItem = {
      ID: selectnode.value.id,
      CREATE_TIME: currRoute.value.CREATE_TIME,
      CREATE_USER: useUserStore().getUserInfo.userId as string,
      UPDATE_TIME: currRoute.value.UPDATE_TIME,
      UPDATE_USER: useUserStore().getUserInfo.userId as string,
      GHOST_ROW: false,
      NODE_NAME: 'N001',
      ROT_ID: currRoute.value.ID,
      SEGMENT: '',
      OPER_CODE: '',
      GPH_TYPE: selectnode.value.type,
      GPH_X: selectnode.value.x,
      GPH_Y: selectnode.value.y,
      GPH_PROP: '',
      GPH_TEXT: selectnode.value.text.value,
      IS_ACTIVE: 'Y',
      IS_CALC_FPY: 'N',
      CAN_SKIP: 'N',
      REMARK: '',
    };
    console.log(routeConfig.currentItem);
    routeConfig.activeKey = 2;
  }
  function handleSuccess(lfInstance) {
    unref(lfInstance).render({});
  }
  function clickBlank() {
    routeConfig.activeKey = 1;
  }
  async function modalSuccess(lfInstance, route) {
    unref(lfInstance).render({});
    currRoute.value = route;
    currRotId.value = currRoute.value.ID;
  }
</script>