yangys
2025-09-25 e4c84d44e70e09ec6d69716bd6c722a953f980da
src/views/wel/shemi.vue
@@ -1,7 +1,7 @@
<template>
  <basic-container>
    <div class="norightmenu" v-if="!isSearch">
      <avue-crud :addBtn="false" :option="option" :table-loading="loading" :data="treeData" ref="crud"
      <avue-crud :addBtn="false" :option="option" :row-style="{height:'20px'}" :cell-style="{padding:'0px'}" :table-loading="loading" :data="treeData" ref="crud"
        v-model:search="search" v-model:page="mypage" @current-change="currentChange" @size-change="sizeChange"
        @refresh-change="refreshChange" @on-load="onLoad" @tree-load="treeLoad" @row-click="rowClick">
        <template #search>
@@ -16,13 +16,13 @@
            </el-col>
            <el-col :span="4" class="search-data-flex">
              <span class="search-data-title">零组件号:</span>
              <el-select v-model="searchTreeData.drawingNo" filterable remote reserve-keyword placeholder="零组件号"
              <el-select v-model="searchTreeData.drawingNo" clearable filterable remote reserve-keyword placeholder="输入至少3个字符过滤数据"
                :remote-method="remoteMethod" :loading="searchLoading">
                <el-option v-for="item in drawingNoList" :key="item.value" :label="item.label"
                  :value="item.value" /></el-select>
            </el-col>
            <el-col :span="8" class="search-data-flex">
              <span class="search-data-title">时间范围:</span>
            <el-col :span="6" class="search-data-flex">
              <span class="search-data-title">时间:</span>
              <el-date-picker v-model="searchTreeData.createTime" type="daterange" start-placeholder="开始时间"
                end-placeholder="结束时间" :size="size" format="YYYY-MM-DD" value-format="YYYY-MM-DD"
                @change="createTimeChange" /><!--:disabled-date="disabledDate" 不需要禁用日期-->
@@ -36,37 +36,29 @@
                  style="margin-right: 6px;">
                  <Delete />
                </el-icon>清空</el-button>
              <el-button type="danger" @click="refresh()">返回目录</el-button>
            </el-col>
          </el-row>
        </template>
        <!-- <template #menu-left>
        <el-button :size="size" type="primary" @click="showAdd()">新增根节点</el-button>
      </template> -->
        <template #name="{ row }">
          <span>{{ row.name }}</span>
          <!-- <el-button :size="size" text v-if="row.nodeType != 70" icon="el-icon-setting" type="primary" placeholder="修改" @click="showEdit(row)" title="修改"></el-button>
        <el-button :size="size" text v-if="row.nodeType != 10" icon="el-icon-delete" type="primary" @click="showDel(row)" placeholder="删除" title="删除"></el-button>
        <el-button :size="size" text v-if="row.nodeType != 60 && row.nodeType != 70" icon="el-icon-document-add" type="primary" @click="showAdd(row)" placeholder="新增子级" title="新增子级"></el-button>
        <el-button :size="size" text v-if="row.nodeType == 60 || row.nodeType == 50" icon="el-icon-upload" type="primary" @click="showUpload(row)" placeholder="文件上传" title="文件上传"></el-button> -->
          <!-- 涉密网才有 -->
          <!-- <el-button :size="size" text v-if="row.nodeType == 70" icon="el-icon-pie-chart" type="primary" @click="upgrade(row)" placeholder="升版" title="升版"></el-button> -->
          <!-- 工控网才有 -->
          <!-- <el-button :size="size" text v-if="row.nodeType == 70" icon="el-icon-position" type="primary" @click="downsend(row)" placeholder="下发" title="下发"></el-button> -->
          <!-- 替换  v-if="permission.auto_dispatch"-->
          <el-button :size="size" text v-if="row.nodeType == 60 && row.parentIds.indexOf('0,1,') > -1"
          <el-tag v-if="row.nodeType == 60" style="margin-left:5px" size="mini" effect="plain">v{{ row.versionNumber }}</el-tag>
          <el-button icon="el-icon-download" @click="handleDownload(row)" class="treebtn" v-if="row.nodeType == 70" :size="size" text title="下载"></el-button>
          <el-button class="treebtn" :size="size" text v-if="permission.replace_button && row.nodeType == 60 && row.parentIds.indexOf('0,1,') > -1"
            icon="el-icon-switch" type="primary" @click="replacement(row)" placeholder="替换" title="替换"></el-button>
          <el-button :size="size" text
            v-if="permission.lock_button && row.nodeType == 60 && row.parentIds.indexOf('0,2') > -1 && row.isLocked != 1"
            icon="el-icon-lock" type="primary" @click="locked(row, true)" placeholder="锁定" title="锁定"></el-button>
          <el-button :size="size" text
            v-if="permission.lock_button && row.nodeType == 60 && row.parentIds.indexOf('0,2') > -1 && row.isLocked == 1"
            icon="el-icon-unlock" type="primary" @click="locked(row, false)" placeholder="解锁" title="解锁"></el-button>
      <!---->
           <el-button icon="el-icon-unlock" class="treebtn" v-if="permission.lock_button && row.nodeType == 60 && row.parentIds.indexOf('0,2') > -1 && row.isLocked != 1"text type="primary" @click="showLockDlg(row)" placeholder="锁定" title="锁定"></el-button>
            <el-button icon="el-icon-lock" class="treebtn" :size="size" text
                v-if="permission.lock_button && row.nodeType == 60 && (row.parentIds.indexOf('0,2') > -1 || row.parentIds.indexOf('0,3') > -1)&& row.isLocked == 1"
              type="primary" @click="showUnLockDlg(row)" placeholder="解锁" title="解锁"></el-button>
        </template>
      </avue-crud>
    </div>
    <div class="norightmenu" v-else>
      <avue-crud :addBtn="false" :option="option" :table-loading="loading" :data="treeData" ref="crud"
      <avue-crud :addBtn="false" :option="option" :row-style="{height:'20px'}" :cell-style="{padding:'0px'}" :table-loading="loading" :data="treeData" ref="crud"
        v-model:search="search" v-model:page="mypage" @current-change="currentChange" @size-change="sizeChange"
        @refresh-change="refreshChange" @on-load="onLoad" @tree-load="treeLoad" @row-click="rowClick">
        <template #search>
@@ -79,15 +71,15 @@
                <el-checkbox value="3" label="偏离" />
              </el-checkbox-group>
            </el-col>
            <el-col :span="4" class="search-data-flex">
            <el-col :span="6" class="search-data-flex">
              <span class="search-data-title">零组件号:</span>
              <el-select v-model="searchTreeData.drawingNo" filterable remote reserve-keyword placeholder="零组件号"
              <el-select v-model="searchTreeData.drawingNo" clearable filterable remote reserve-keyword placeholder="输入至少3个字符过滤数据"
                :remote-method="remoteMethod" :loading="searchLoading">
                <el-option v-for="item in drawingNoList" :key="item.value" :label="item.label"
                  :value="item.value" /></el-select>
            </el-col>
            <el-col :span="8" class="search-data-flex">
              <span class="search-data-title">时间范围:</span>
            <el-col :span="6" class="search-data-flex">
              <span class="search-data-title">时间:</span>
              <el-date-picker v-model="searchTreeData.createTime" type="daterange" start-placeholder="开始时间"
                end-placeholder="结束时间" :size="size" format="YYYY-MM-DD" value-format="YYYY-MM-DD"
                @change="createTimeChange" /><!--:disabled-date="disabledDate" 不需要禁用日期-->
@@ -101,6 +93,7 @@
                  style="margin-right: 6px;">
                  <Delete />
                </el-icon>清空</el-button>
                <el-button type="danger" @click="refresh()">返回目录</el-button>
            </el-col>
          </el-row>
        </template>
@@ -109,41 +102,27 @@
      </template> -->
        <template #name="{ row }">
          <span>{{ row.name }}</span>
          <!-- <el-button :size="size" text v-if="row.nodeType != 70" icon="el-icon-setting" type="primary" placeholder="修改" @click="showEdit(row)" title="修改"></el-button>
        <el-button :size="size" text v-if="row.nodeType != 10" icon="el-icon-delete" type="primary" @click="showDel(row)" placeholder="删除" title="删除"></el-button>
        <el-button :size="size" text v-if="row.nodeType != 60 && row.nodeType != 70" icon="el-icon-document-add" type="primary" @click="showAdd(row)" placeholder="新增子级" title="新增子级"></el-button>
        <el-button :size="size" text v-if="row.nodeType == 60 || row.nodeType == 50" icon="el-icon-upload" type="primary" @click="showUpload(row)" placeholder="文件上传" title="文件上传"></el-button> -->
          <!-- 涉密网才有 -->
          <!-- <el-button :size="size" text v-if="row.nodeType == 70" icon="el-icon-pie-chart" type="primary" @click="upgrade(row)" placeholder="升版" title="升版"></el-button> -->
          <!-- 工控网才有 -->
          <!-- <el-button :size="size" text v-if="row.nodeType == 70" icon="el-icon-position" type="primary" @click="downsend(row)" placeholder="下发" title="下发"></el-button> -->
          <el-tag v-if="row.nodeType == 60" style="margin-left:5px" size="mini" effect="plain">v{{ row.versionNumber }}</el-tag>
          <el-button icon="el-icon-download" @click="handleDownload(row)" class="treebtn" v-if="row.nodeType == 70" :size="size" text title="下载"></el-button>
          <!-- 替换  v-if="permission.auto_dispatch"-->
          <el-button :size="size" text v-if="row.nodeType == 60 && row.parentIds.indexOf('0,1,') > -1"
          <el-button class="treebtn" :size="size" text v-if="permission.replace_button && row.nodeType == 60 && row.parentIds.indexOf('0,1,') > -1"
            icon="el-icon-switch" type="primary" @click="replacement(row)" placeholder="替换" title="替换"></el-button>
          <el-button :size="size" text
          <el-button class="treebtn" :size="size" text
            v-if="permission.lock_button && row.nodeType == 60 && row.parentIds.indexOf('0,2') > -1 && row.isLocked != 1"
            icon="el-icon-lock" type="primary" @click="locked(row, true)" placeholder="锁定" title="锁定"></el-button>
          <el-button :size="size" text
            v-if="permission.lock_button && row.nodeType == 60 && row.parentIds.indexOf('0,2') > -1 && row.isLocked == 1"
            icon="el-icon-unlock" type="primary" @click="locked(row, false)" placeholder="解锁" title="解锁"></el-button>
            icon="el-icon-unlock" type="primary" @click="showLockDlg(row)" placeholder="锁定" title="锁定"></el-button>
          <el-button class="treebtn" :size="size" text
            v-if="permission.lock_button && row.nodeType == 60 && (row.parentIds.indexOf('0,2') > -1 || row.parentIds.indexOf('0,3') > -1)&& row.isLocked == 1"
            icon="el-icon-lock" type="primary" @click="showUnLockDlg(row)" placeholder="解锁" title="解锁"></el-button>
        </template>
      </avue-crud>
    </div>
    <!-- 新增节点 -->
    <el-dialog :title="modalTitle" append-to-body v-model="modalBox">
      <avue-form :option="modalOption" v-model="modalForm" @submit="modalSubmit" @reset-change="modalCancel" />
    <!-- 锁定对话框 -->
    <el-dialog title="程序锁定" append-to-body v-model="lockBox">
      <avue-form :option="lockOption" v-model="lockForm" @submit="lockSubmit" @reset-change="lockCancel" />
    </el-dialog>
    <el-dialog title="上传文件" append-to-body v-model="uploadmodalBox">
      <avue-form :option="uploadmodalOption" v-model="uploadmodalForm" @submit="uploadmodalSubmit"
        @reset-change="uploadmodalCancel" :upload-before="uploadBefore" :upload-after="uploadAfter">
        <template #fileList="{ }" slot-scope="{ value }">
          <div v-for="(file, index) in fileList" :key="index" v-if="fileList.length != 0">
            {{ file.name }}
          </div>
          <div v-else>没有上传文件</div>
        </template>
      </avue-form>
    <el-dialog title="程序解锁" append-to-body v-model="unlockBox">
      <avue-form :option="unlockOption" v-model="unlockForm" @submit="unlockSubmit" @reset-change="unlockCancel" />
    </el-dialog>
    <avue-tabs :option="tabsOption" @change="tabsHandleChange" style="margin-top: 30px;" v-if="isShowTabs"></avue-tabs>
    <avue-form v-if="tabsType == 'tab1'" :option="tabsFormOption" v-model="tabsForm"></avue-form>
@@ -152,19 +131,38 @@
      <div v-html="convertToHtml(fileContent)" class="convertToHtml"></div>
    </template>
    <template v-else-if="tabsType == 'tab4'">
      <!--
      <avue-crud :addBtn="false" :option="tabsFormOption4" :data="tabsForm4" ref="crud4"
        @selection-change="selectionChange">
        <template #menu-left>
          <el-button :size="size" type="primary" @click="comparison"
            :disabled="selectionList.length != 2">对比</el-button>
        </template>
      </avue-crud>
          -->
      <el-table :data="tabsForm4" border :row-style="{height:'20px'}" :cell-style="{padding:'0px'}" max-height="220" highlight-current-row>
            <el-table-column type="index" label="#" width="40" align="center" />
            <el-table-column prop="name" label="程序包名">
            </el-table-column>
            <el-table-column prop="versionNumber" label="程序版本">
            </el-table-column>
            <el-table-column prop="createTime" label="创建时间">
            </el-table-column>
            <el-table-column prop="createUserName" label="创建人">
            </el-table-column>
            <el-table-column fixed="right" label="操作" width="150" align="center">
                <template #default="scope">
                    <a style="color: blue;cursor: pointer;font-size: 12px;margin-right: 4px;" type="text" size="small"
                        @click.stop="showHisFileDlg(scope.$index, scope.row)">程序文件</a>
                </template>
            </el-table-column>
        </el-table>
    </template>
    <el-dialog title="升版" append-to-body v-model="upgradeModal" width="500">
      <avue-form :option="upgradeModalOption" v-model="upgradeModalForm" @submit="upgradeSubmit"
        @reset-change="upgradeCancel"></avue-form>
    </el-dialog>
  </basic-container>
  <!-- 文件对比 -->
  <el-drawer title="文件对比" append-to-body v-model="diffBox" size="100%" class="code-box">
@@ -173,33 +171,59 @@
        :filename="codeDiffFileName1" :newFilename="codeDiffFileName2" />
    </div>
  </el-drawer>
  <el-dialog title="查看历史文件" append-to-body v-model="hisFileViewModel">
      <el-table :data="hisFileTableData" ref="hisFilesTable" border @row-click="showHisContent" max-height="200" highlight-current-row>
        <el-table-column type="index" label="#" width="40" align="center"/>
        <el-table-column prop="name" label="文件名称"></el-table-column>
        <el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
        <el-table-column fixed="right" label="操作" width="80" align="center">
            <template #default="scope">
                <a style="color: blue;cursor: pointer;font-size: 12px;margin-right: 4px;" type="text" size="small"
                    @click.stop="handleDownload(scope.row)">下载</a>
            </template>
        </el-table-column>
      </el-table>
      <h4>程序内容</h4>
      <div v-html="hisFileContent" class="app-content"></div>
  </el-dialog>
  <!-- 替换 -->
  <el-drawer title="替换" append-to-body v-model="todolistModel" size="100%" class="code-box">
  <el-drawer title="替换" append-to-body v-model="replaceModel" size="100%" class="code-box">
    <div class="approve-box">
      <div class="left">
        <TodolistLeft :row="row" :replaceDataId="replaceDataId" :drawingNo="drawingNo" :processNo="processNo"
        <ReplaceLeft ref="replaceLeft" v-if="replaceModel" :row="row" :replaceDataId="replaceDataId" :drawingNo="drawingNo" :processNo="processNo"
          :processEdition="processEdition" @selection-change="todoSelectionChange" />
      </div>
      <div class="right">
        <TodolistRightTop :row="row" :name="name" />
        <avue-form ref="form" :option="optionApprove" v-model="formApprove" @submit="handleSubmit" />
        <ReplaceRightTop :row="row" :name="name" />
        <avue-form ref="form" :option="optionApprove" v-model="formApprove" @submit="handleReplace" />
      </div>
    </div>
  </el-drawer>
</template>
<script>
import { Delete, Edit, Search, Share, Upload ,Lock,Unlock} from '@element-plus/icons-vue'
import debounce from 'lodash/debounce';
import NProgress from 'nprogress';
import { downloadXls } from '@/utils/util';
import { exportBlob } from '@/api/common';
import { ElMessage } from 'element-plus';
import TodolistLeft from './components/TodolistLeft.vue';
import TodolistRightTop from './components/TodolistRightTop.vue';
import ReplaceLeft from './components/ReplaceLeft.vue';
import ReplaceRightTop from './components/ReplaceRightTop.vue';
import qs from 'qs';
export default {
  components: {
    TodolistLeft,
    TodolistRightTop
    ReplaceLeft,
    ReplaceRightTop
  },
  data() {
    let rejectText = '驳回';//+this.row.categoryName;
    return {
      size:'large',//树里按钮的尺寸
      isSearch: null,
      treeSearchLoad: false,
      drawingNoList: [],
@@ -276,7 +300,7 @@
      },
      applist: [],
      row: {},
      todolistModel: false,
      replaceModel: false,
      diffBox: false,
      content1: "",
      content2: "",
@@ -284,55 +308,50 @@
      codeDiffFileName2: "",
      selectionList: [],
      targetRow: {},
      upgradeModal: false,
      file: null,
      fileContent: "",
      isShowTabs: true,
      nodeTypeList: [],
      fileList: [],
      tabsType: "tab1",
      upgradeModalForm: {},
      upgradeModalOption: {
        emptyText: "取消",
        menuPosition: "right",
        column: [{
          label: '工序版次',
          prop: 'processEdition',
          labelWidth: "80",
          span: 22
        }]
      },
      tabsOption: {},
      tabsOption1: {
        column: [{
          icon: 'el-icon-info',
          label: '节点信息',
          prop: 'tab1',
        }/*, {
          icon: 'el-icon-warning',
          label: '版本信息',
          prop: 'tab2',
        }*/]
        }
      ]
      },
      tabsOption2: {
        column: [{
          icon: 'el-icon-info',
          label: '节点信息',
          prop: 'tab1',
        },/* {
          icon: 'el-icon-warning',
          label: '版本信息',
          prop: 'tab2',
        }, */{
        },
        {
          icon: 'el-icon-warning',
          label: '文件内容',
          prop: 'tab3'
        }, {
        }
        ]
      },
      tabsOptionPackage: {
        column: [{
          icon: 'el-icon-info',
          label: '节点信息',
          prop: 'tab1',
        },
        {
          icon: 'el-icon-warning',
          label: '历史记录',
          prop: 'tab4'
        }]
      },
      hisFileViewModel: false,//历史文件列表对话框
      hisFileTableData:[], //历史文件列表数据
      hisFileContent:'',//历史文件内容
      tabsFormOption: {
        submitBtn: false,
        emptyBtn: false,
@@ -360,85 +379,77 @@
            prop: 'createTime',
            disabled: true,
            placeholder: " "
          },/*
          {
            label: '节点描述',
            prop: 'description',
            disabled: true,
            placeholder: " "
          },*/
          },
          {
            label: '修改时间',
            prop: 'updateTime',
            disabled: true,
            placeholder: " "
          }/*,
          {
            label: '备注',
            prop: 'remark',
            disabled: true,
            placeholder: " "
          }*/
          }
        ]
      },
      tabsForm: {},
      uploadmodalBox: false,
      uploadmodalForm: {},
      selectedColumn: {},
      modalForm: {},
      modalOption: {
        submitText: "保存",
      lockOption: {
        submitText: "锁定",
        emptyText: "取消",
        menuPosition: "right",
        column: [
          {
            label: '节点类型1',
            prop: 'nodeType',
            labelWidth: "120",
            type: 'select',
            dicUrl: '/blade-system/dict-biz/dictionary?code=nc_node_type',
            props: {
              label: 'dictValue',
              value: 'dictKey',
            },
            disabled: true
          },
          {
            label: '设备(机床)',
            prop: 'machineCode',
            labelWidth: "120",
            type: 'select',
            dicUrl: '/blade-mdm/machine/page',
            props: {
              label: 'name',
              value: 'code',
            },
            dicFormatter(res) {
              return res.data.records;
            }
          },
          {
            label: '节点名称',
            label: '程序包名',
            prop: 'name',
            disabled:true,
            labelWidth: "120",
          },
          {
            label: '节点描述',
            prop: 'description',
            labelWidth: "120",
            hide: true
          },
          {
            label: '备注',
            label: '锁定原因',
            prop: 'remark',
            type: "textarea",
            labelWidth: "120",
            span: 24
            span: 24,
            rules: [{ required: true, message: '必填', trigger: 'blur' }],
          }
        ]
      },
      modalBox: false,
      modalTitle: "",
      lockForm: {},
      lockBox: false,
      unlockOption: {
        submitText: "启动解锁流程",
        emptyText: "取消",
        menuPosition: "right",
        column: [
          {
            label: '程序包名',
            prop: 'name',
            disabled:true,
            labelWidth: "120",
          },
          {
            label: '锁定原因',
            prop: 'remark',
            type: "textarea",
            placeholder:'<内容为空>',
            disabled:true,
            labelWidth: "120",
            span: 24,
          },
          {
            label: '解锁原因',
            prop: 'unlockReason',
            type: "textarea",
            labelWidth: "120",
            span: 24,
          }
        ]
      },
      unlockForm: {},
      unlockBox: false,
      id: "",
      parentId: 1,
      loading: true,
@@ -447,6 +458,7 @@
        current: 1,
        total: 0,
      },
      /*
      tabsFormOption4: {
        rowKey: "id",
        selection: true,
@@ -461,7 +473,7 @@
          { label: '创建时间', prop: 'createTime' },
          { label: '创建人', prop: 'createUserName' },
        ]
      },
      },*/
      tabsForm4: {},
      defaultExpandedKeys: [],
      option: {
@@ -493,10 +505,10 @@
          {
            label: '目录',
            prop: 'name',
            width: '360'
            width: '420'
          },
          {
            label: '版本',
          /*{
            label: '程序版本',
            prop: 'versionNumber',
            formatter: (val, value, label) => {
              if (val.nodeType == '60') {
@@ -509,31 +521,11 @@
                return '';
              }
            }
          },/*
          {
            label: '版次',
            prop: 'processEdition',
            formatter: (val, value, label) => {
                if(val.nodeType == '60'){
                    return value;
                }else{
                    return '';
                }
            }
          },
          {
            label: '描述',
            prop: 'abc'
          },*/
          {
            label: '类型',
            prop: 'nodeTypeName'
          },/*
          {
            label: '设备',
            prop: 'machineCode'
          },
          */
          {
            label: '锁定状态',
            prop: 'isLocked',
@@ -567,11 +559,7 @@
                }
              }
            },
          },/*
          {
            label: '测试程序',
            prop: 'abc'
          },*/
          },
          {
            label: '创建人',
            prop: 'createUserName',
@@ -585,143 +573,11 @@
        ],
      },
      treeData: [],
      upData: []
    };
  },
  computed: {
    ...mapGetters(['userInfo', 'permission']),
    uploadmodalOption() {
      return {
        submitText: "保存",
        emptyText: "取消",
        menuPosition: "right",
        column: [
          {
            label: '节点类型',
            prop: 'nodeType',
            labelWidth: "120",
            type: 'select',
            dicUrl: '/blade-system/dict-biz/dictionary?code=nc_node_type',
            props: {
              label: 'dictValue',
              value: 'dictKey',
            },
            disabled: true
          },
          {
            label: '设备编号',
            prop: 'machineCode',
            labelWidth: "120",
            type: 'select',
            dicUrl: '/blade-mdm/machine/page',
            props: {
              label: 'name',
              value: 'code',
            },
            dicFormatter(res) {
              return res.data.records;
            },
            rules: [
              {
                required: true,
                message: '请输入设备编号',
                trigger: 'blur'
              }
            ]
          },
          {
            label: '零组件号/图号',
            prop: 'drawingNo',
            labelWidth: "120",
            rules: [
              {
                required: true,
                message: '请输入零组件号/图号',
                trigger: 'blur'
              }
            ]
          },
          {
            label: '工序',
            prop: 'processName',
            labelWidth: "120",
            rules: [
              {
                required: true,
                message: '请输入工序',
                trigger: 'blur'
              }
            ]
          },
          {
            label: '工序版本',
            prop: 'processEdition',
            labelWidth: "120",
            rules: [
              {
                required: true,
                message: '请输入工序版本',
                trigger: 'blur'
              }
            ]
          },
          {
            label: '文件分类',
            prop: 'category',
            labelWidth: "120",
            type: 'select',
            dicUrl: '/blade-system/dict-biz/dictionary?code=node_file_type',
            props: {
              label: 'dictValue',
              value: 'dictKey',
            },
            rules: [
              {
                required: true,
                message: '请选择文件分类',
                trigger: 'change'
              }
            ]
          },
          {
            label: '选择文件',
            prop: 'uploadFile',
            labelWidth: "120",
            type: 'upload',
            data: { nodeId: this.id },
            action: "",
            showFileList: false,
            span: 24,
            tip: "请上传文件,将在提交时统一处理",
            action: "/blade-mdm/program/ncfile/upload",
            rules: [
              {
                validator: (rule, value, callback) => {
                  if (this.fileList.length === 0) {
                    callback(new Error('请上传文件'));
                  } else {
                    callback();
                  }
                },
                trigger: 'blur'
              }
            ]
          },
          {
            label: '已上传文件',
            prop: 'fileList',
            labelWidth: "120"
          },
          {
            label: '备注',
            prop: 'remark',
            type: "textarea",
            labelWidth: "120",
            span: 24
          }
        ]
      }
    }
  },
  watch: {
@@ -742,14 +598,24 @@
      return time.getTime() > today.getTime() || time.getTime() < threeMonthsAgo.getTime();//
    },
    createTimeChange(value) {
      console.log('createTimeChange', value)
      this.searchTreeData.createTimeBegin = value[0];
      this.searchTreeData.createTimeEnd = value[1];
    },
    remoteMethod(query) {
      if (query) {
      if (query && query.length>2) {
        this.searchLoading = true;
        axios({
        this.getRemote(query);
      } else {
        this.drawingNoList = [];
      }
    },
    getRemote: debounce(function(query){
            //防抖,这里设置600毫秒请求一次后台
            this.getList(query)
    },600),
    async getList(query){
      this.searchLoading = false;
      axios({
          url: '/blade-mdm/program/node/drawing-no-pick',
          method: 'get',
          params: { drawingNo: query }
@@ -761,36 +627,146 @@
          })
          this.drawingNoList = drawingNoList;
        });
      } else {
        this.drawingNoList = [];
      }
    },
    locked(row, isLockP) {
      //row.isLocked == isLock
      var isLock = row.isLocked == 1;
      console.log('isLock', isLock)
      this.$confirm(`是否${isLock ? '解锁' : '锁定'}`, {
    refresh(){
      //表格重置
      this.treeData=[];
      //this.$refs.curd.refreshTable();
      let curS = this.isSearch;
      this.isSearch = null;
      this.onLoad();
      this.isSearch = !curS
    },
    handleDownload(row){
      NProgress.start();
      exportBlob(
          `/blade-mdm/program/nodehis/download-by-nodeid?nodeId=${row.id}`
      ).then(res => {
          if (res.status !== 200) {
              return this.$message.error(res.msg);
          }
          downloadXls(res.data, `${row.name}`);
          NProgress.done();
      });
    },
    showLockDlg(row){
      //this.lockForm = row;
      this.lockForm.id = row.id;
      this.lockForm.name = row.name
      this.lockForm.parentId = row.parentId;
      this.lockForm.remark = '';
      this.lockBox = true;
    },
    lockCancel() {
      this.lockBox = false;
      this.lockForm = {};
    },
    showUnLockDlg(row){
      this.unlockForm.id = row.id;
      this.unlockForm.name = row.name
      this.unlockForm.remark = row.remark;
      this.unlockForm.unlockReason='';
      this.unlockForm.parentId = row.parentId;
      this.unlockBox = true;
    },
    lockSubmit(row,done) {
      //锁定提交
      this.$confirm('是否锁定', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(() => {
        axios.post('/blade-mdm/program/node/lock',qs.stringify(this.lockForm)).then(res=>{
          if (res.data.code == 200) {
            this.$message({ type: 'success', message: '操作成功!' });
            this.addLocalTreeNode(this.lockForm.parentId);
            this.lockBox = false;
          } else {
            this.$message({ type: 'error', message: res.data.msg });
          }
          this.lockBox = false;
        }).catch(error => {
          this.$message({ type: 'error', message: res.data.msg });
        });
        done();
      }).catch(action => {
        console.log('cancel')
      });
    },
    unlockSubmit(row,done) {
      //启动解锁流程
      this.$confirm(`确认解锁`, {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(() => {
        axios({
          url: isLock ? '/blade-mdm/flow/lock/start-unlock' : '/blade-mdm/program/node/lock',
          url: '/blade-mdm/flow/lock/start-unlock',
          method: 'post',
          params: { id: row.id, nodeId: row.id }
          params: {nodeId: row.id,unlockReason:row.unlockReason }
        }).then(res => {
          if (res.data.code == 200) {
            this.$message({ type: 'success', message: '操作成功!' });
            this.addLocalTreeNode(row.parentId);
            this.$message({ type: 'success', message: '解锁流程已启动!' });
            //this.addLocalTreeNode(row.parentId);
            this.unlockBox = false;
          } else {
            this.$message({ type: 'success', message: res.data.msg });
            this.$message({ type: 'error', message: res.data.msg });
          }
        });
        done();
      }).catch(action => {
        console.log('cancel')
      });
    },
    handleSubmit(form, done) {
    unlockCancel() {
      this.unlockBox = false;
    },
    replacement(row) {  //替换
      this.id = row.id;
      this.formApprove = {
        comment: '',
        approve: 'Y', // 默认同
      }
      //准备程序替换流程
      axios({
        url: '/blade-mdm/flow/replace/pre',
        method: 'post',
        params: { nodeId: row.id }
      }).then(resp => {
        this.row = row;
        this.drawingNo = resp.data.data.drawingNo;
        this.replaceDataId = resp.data.data.processInstanceId;
        //console.log('replaceDataId',this.replaceDataId)
        this.processNo = resp.data.data.processNo;
        this.processEdition = resp.data.data.processEdition;
        this.formApprove.title = resp.data.data.name + "替换";
        this.getHandler(); //获取处理人
        this.$nextTick(() => {
          //等待dom更新再显示界面
          this.replaceModel = true;
        })
      });
    },
    getHandler() {  //获取处理人
      axios({
        url: '/blade-mdm/flow/replace/default-assignees',
        method: 'get',
        params: { drawingNo: this.drawingNo }
      }).then(
        resp => {
          if (resp.data.code == 200) {
            this.formApprove.assignee = resp.data.data.checkerId;
          } else {
            this.$message.success(resp.msg);
          }
        });
    },
    handleReplace(form, done) {
      //发起程序替换流程
      var obj = {
        title: this.formApprove.title,
@@ -809,75 +785,54 @@
          message: '操作成功!',
        });
        done();
        this.todolistModel = false;
        this.replaceModel = false;
      }).catch(error => {
        window.console.log('haha', error);
        done();
      });
      // if(this.row.taskDefinitionKey === 'programmingTask') {
      //     // if(this.applist.length !== 1) {
      //     //     done();
      //     //     return this.$message.success('请选择1个程序');
      //     // }
      // }
      // approve({
      //     ...this.formApprove,
      //     taskId: this.row.taskId,
      //     processInstanceId: this.row.processInstanceId,
      //     // programIds: this.row.taskDefinitionKey === 'programmingTask' ? this.applist.map(v => v.id).join(',') : '',
      // }).then(res => {
      //     if(res.data.code !== 200) {
      //         this.$message.error(res.data.msg);
      //         done();
      //         return;
      //     }
      //     this.$message.success('审批成功');
      //     this.approveBox = false;
      //     this.onLoad(this.page, this.query);
      //     done();
      // }).catch(err => {
      //     done();
      //     console.error(err);
      // });
    },
    showHisFileDlg(index,row){
      this.hisFileViewModel = true;
      //查询文件列表
      axios({
        url: '/blade-mdm/program/nodehis/files-by-parent-id',
        method: 'get',
        params: {id: row.id}
      }).then(
      res => {
        if(res.data.code === 200) {
          this.hisFileTableData = res.data.data;
          if(this.hisFileTableData.length > 0){
            this.showHisContent(this.hisFileTableData[0])
            this.$refs.hisFilesTable.setCurrentRow(this.hisFileTableData[0]);
          }
        } else {
          this.$message.error('程序内容加载失败');
        }
      });
    },
    showHisContent(row, column, event) {
      axios({
        url: '/blade-mdm/program/nodehis/content-by-nodeid',
        method: 'get',
        params: {nodeId: row.id}
      }).then(
      res => {
        if(res.data.code === 200) {
            this.hisFileContent = res.data.data;
        } else {
            this.hisFileContent = '程序内容加载失败'
        }
      });
    },
    todoSelectionChange(applist) {
      this.applist = applist;
    },
    replacement(row) {  //替换
      this.id = row.id;
      this.formApprove = {
        comment: '',
        approve: 'Y', // 默认同
      }
      //准备程序替换流程
      axios({
        url: '/blade-mdm/flow/replace/pre',
        method: 'post',
        params: { nodeId: row.id }
      }).then(resp => {
        this.row = row;
        this.replaceDataId = resp.data.data.processInstanceId;
        this.processNo = resp.data.data.processNo;
        this.processEdition = resp.data.data.processEdition;
        this.drawingNo = resp.data.data.drawingNo;
        this.formApprove.title = resp.data.data.name + "替换";
        this.getHandler(); //获取处理人
        this.todolistModel = true;
      });
    },
    getHandler() {  //获取处理人
      axios({
        url: '/blade-mdm/flow/replace/default-assignees',
        method: 'get',
        params: { drawingNo: this.drawingNo }
      }).then(
        resp => {
          if (resp.data.code == 200) {
            this.formApprove.assignee = resp.data.data.checkerId;
          } else {
            this.$message.success(resp.msg);
          }
        });
    },
    convertToHtml(text) {
      return text.replace(/\n/g, '<br>');
@@ -906,7 +861,6 @@
      return treeData.map(node => {
        if (node.children && node.children.length > 0) {
          this.defaultExpandedKeys.push(node.id);
          console.log('>>>>>>>>', this.defaultExpandedKeys)
          node.children = this.removeHasChildren(node.children);
        }
        if (node.children.length > 0) {
@@ -919,8 +873,11 @@
      });
    },
    searchTree() {
      if (this.searchTreeData.programStatus.length == 0) return;
      if (this.searchTreeData.drawingNo == "") return;
      if (this.searchTreeData.programStatus.length == 0 || !this.searchTreeData.drawingNo){
        this.$message.warning('请输入程序状态和零组件号进行搜索');
        return;
      }
      this.treeSearchLoad = true;
      this.isSearch = !this.isSearch
      this.searchTreeData.status = this.searchTreeData.programStatus.join();
@@ -939,7 +896,6 @@
        };
        // this.option.defaultExpandAll = true;
        let treeData = this.removeHasChildren(res.data.data);
        console.log('treeData', treeData)
        this.option = Object.assign({},this.option,{defaultExpandedKeys: this.defaultExpandedKeys,lazy: true,defaultExpandAll: true});
        setTimeout(() => {
          this.treeSearchLoad = false;
@@ -957,7 +913,7 @@
          if (this.treeData.length == 0) {
            return;
          }
        }, 1000);
        }, 100);
      });
@@ -977,23 +933,7 @@
        this.onLoad();
      })
    },
    upgradeSubmit(row, done) {  //升版
      axios({
        url: '/blade-mdm/program/ncfile/upgrade-process-edition',
        method: 'post',
        params: { bindNcNodeId: row.id, newProcessEdition: row.processEdition },
      }).then(
        res => {
          done();
          this.upgradeModal = false;
          this.$message.success('操作成功');
          this.addLocalTreeNode(row.parentId);
        }
      );
    },
    upgradeCancel() {
      this.upgradeModal = false;
    },
    downsend(row) {  //下发
      this.loading = true;
      axios({
@@ -1025,64 +965,7 @@
        }
      );
    },
    uploadBefore(file, done, loading, column) {
      this.file = file;
      this.fileList.push(file);
      //done();  放开就上传了
      return false;
    },
    uploadAfter() {
    },
    uploadmodalSubmit(row, done) {  //上传提交接口
      if (this.file == null) {
        this.$message.error('请上传文件');
        return;
      }
      var formData = new FormData();
      formData.append('file', this.file);
      formData.append('nodeId', this.id);
      if (this.isRepeatUpload) {
        formData.append('cofirm', '1');
      }
      Object.keys(this.uploadmodalForm).forEach(key => {
        formData.append(key, this.uploadmodalForm[key]);
      });
      this.loading = true;
      axios({
        url: '/blade-mdm/program/ncfile/upload',
        method: 'post',
        data: formData,
      }).then(res => {
        this.loading = false;
        if (res.data.code == 2) {
          this.$confirm('文件名已存在,确定上传吗?', '提示', {
            distinguishCancelAndClose: true,
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            this.isRepeatUpload = true;
            this.uploadmodalSubmit(row, done);
          }).catch(action => {
            this.isRepeatUpload = false;
            this.$message({
              type: 'info',
              message: '取消上传'
            })
          });
        } else if (res.data.success) {
          this.isRepeatUpload = false;
          this.uploadmodalBox = false;
          this.$message({ type: 'success', message: '操作成功!' });
          this.addLocalTreeNode(row.id);  //重新加载下一级
        } else {
          this.isRepeatUpload = false;
          alert(1)
        }
        done();
      }
      );
    },
    rowClick(row) {
      this.tabsForm = row;
      this.id = row.id;
@@ -1092,17 +975,22 @@
          this.tabsForm.nodeTypeName = item.dictValue;
        }
      })
      if (this.tabsForm.nodeType != 70) {
        this.tabsOption = this.tabsOption1;
      } else {
        this.tabsOption = this.tabsOption2;
        //获取文件list
        this.getFile(row.id);
      if (this.tabsForm.nodeType == 60) {
        //包名节点
        this.tabsOption = this.tabsOptionPackage;
        //获取历史记录
        this.getHistory(row.id);
      } else if (this.tabsForm.nodeType == 70){
        //文件节点
        this.tabsOption = this.tabsOption2;
        //获取文件内容
        this.getFile(row.id);
        //清空对比记录
        this.content1 = "";
        this.content2 = "";
      }else{
        this.tabsOption = this.tabsOption1;
      }
      this.$nextTick(() => {
        this.tabsType = 'tab1';
@@ -1112,26 +1000,11 @@
    tabsHandleChange(tabs) {
      this.tabsType = tabs.prop;
    },
    showUpload(row) {//获取附件内容(暂时没用)
      this.fileList = [];
      this.uploadmodalForm = row;
      this.loading = true;
      var obj = { parentId: row.id }
      axios({
        url: '/blade-mdm/program/node/lazy-list',
        method: 'get',
        params: obj,
      }).then(
        res => {
          this.loading = false;
          this.uploadmodalBox = true;
        }
      );
    },
    getFile(id) { //查看文件内容
      this.loading = true;
      axios({
        url: '/blade-mdm/program/ncfile/content-by-nodeid',
        url: '/blade-mdm/program/nodehis/content-by-nodeid',
        method: 'get',
        params: { nodeId: id },
      }).then(
@@ -1144,7 +1017,7 @@
    getHistory(id) {  //查看历史记录
      this.loading = true;
      axios({
        url: '/blade-mdm/program/node/history-by-nodeid',
        url: '/blade-mdm/program/nodehis/history-by-nodeid',
        method: 'get',
        params: { id },
      }).then(
@@ -1174,86 +1047,7 @@
    selectionChange(list) {
      this.selectionList = list;
    },
    showEdit(row, done) {
      this.modalTitle = "修改";
      this.modalBox = true;
      this.modalForm = row;
    },
    showDel(row) {
      this.$confirm('将会删除该节点及其子节点,是否确认删除?', {
        confirmButtonText: '是',
        cancelButtonText: '否',
        type: 'warning',
      }).then(() => {
        //调用接口
        this.loading = true;
        axios({
          url: '/blade-mdm/program/node/remove',
          method: 'post',
          params: { id: row.id },
        }).then(
          res => {
            this.loading = false;
            this.addLocalTreeNode(row.parentId);
          }
        );
      })
    },
    showAdd(row) {  //新增子节点
      if (!row) {
        this.modalTitle = "新增根节点";
        this.modalForm.nodeType = this.nodeTypeList[0].dictKey;
        this.modalForm.parentId = 0;
      } else {
        if (row.nodeType == 60) { //程序包
          return;
        }
        var defalutNodeType = "";  //下一级节点类型
        for (var i = 0; i < this.nodeTypeList.length; i++) {
          if (row.nodeType == this.nodeTypeList[i].dictKey) {
            defalutNodeType = this.nodeTypeList[i + 1].dictKey;
          }
        }
        this.modalTitle = "新增子节点";
        this.selectedColumn.nodeType = defalutNodeType;
        this.selectedColumn.parentId = row.id;
        this.selectedColumn.name = "";
        this.selectedColumn.id = "";
        this.modalForm = this.selectedColumn;
      }
      this.modalBox = true;
    },
    modalSubmit(row, done) {  //新增子节点保存/修改
      if (this.modalTitle == "修改") {
        var url = "/blade-mdm/program/node/update";
      } else {
        var url = "/blade-mdm/program/node/save";
      }
      //调用接口
      this.loading = true;
      axios({
        url,
        method: 'post',
        data: this.modalForm,
      }).then(
        res => {
          this.$message.success('操作成功');
          this.modalBox = false;
          // 修改,更新本地数据
          if (this.modalTitle === "修改") {
            this.addLocalTreeNode(row.parentId);
          } else {
            // 如果是新增操作,可能需要重新加载数据
            //this.$refs.crud.refreshTable();
            //this.onLoad();
            //新增,更新本地数据
            this.addLocalTreeNode(row.parentId);
          }
          this.loading = false;
          done(row);
        }
      );
    },
    addLocalTreeNode(parentId) {
      if (this.modalTitle == "新增根节点") {
        this.onLoad();
@@ -1271,20 +1065,14 @@
          if (parentId == 0) {
            this.treeData = [...children];
          } else {
            this.$refs.crud.$refs.table.store.states.lazyTreeNodeMap.value[parentId] = [...children];
          }
          this.loading = false;
        }
      );
    },
    modalCancel() {
      this.modalBox = false;
    },
    uploadmodalCancel() {
      this.uploadmodalBox = false;
    },
    treeLoad(tree, treeNode, resolve) {
      console.log('tree', tree, treeNode, this.option)
      this.loading = true;
      var obj = { parentId: tree.id }
      
@@ -1335,9 +1123,7 @@
        }
      );
    },
    getPre() {
      alert(1)
    },
    subtractMonths(date, months) {
      const newDate = new Date(date);
      const currentMonth = newDate.getMonth();
@@ -1372,6 +1158,9 @@
</script>
<style lang="scss">
.treebtn {
   font-size:16px;
}
.norightmenu .avue-crud .avue-crud__header {
  display: none !important;
}
@@ -1431,7 +1220,7 @@
}
.search-data-title {
  font-size: 12px;
  font-size: 14px;
  margin-right: 8px;
  display: inline-block;
  width: 95px;