From ba9490368b8bf27e0d4a6471420044dadf5b720e Mon Sep 17 00:00:00 2001
From: zhaowei <zhaowei>
Date: 星期二, 21 一月 2025 15:33:42 +0800
Subject: [PATCH] 产品结构树: 1、新增指定文档为当前版本功能与文档版本内容差异比对功能(新增插件vue-code-diff) 2、调整产品及部件属性tab栏标题为属性信息 3、删除产品及部件属性信息中对应层级名称 全局: 调整设置后端接口地址方式由vue.config.js改为env环境文件配置

---
 src/views/dnc/base/modules/ProductStructure/Document/DocumentModalForm.vue        |    2 
 src/views/dnc/base/modules/ProductStructure/Document/FileCompareModal.vue         |   77 ++++++
 vue.config.js                                                                     |    9 
 package-lock.json                                                                 |  159 +++++++++++++
 src/views/dnc/base/modules/ProductStructure/Document/DocumentVersionTableList.vue |   95 ++++++-
 src/views/dnc/common/TableContextMenu.vue                                         |    6 
 src/views/dnc/common/ImportFileModal.vue                                          |    8 
 src/views/dnc/base/modules/ProductStructure/Document/SelectFileCompareModal.vue   |  134 +++++++++++
 src/views/dnc/base/modules/ProductStructure/Product/ProductInfo.vue               |    6 
 src/utils/request.js                                                              |    3 
 src/views/dnc/base/modules/ProductStructure/Component/ComponentInfo.vue           |    6 
 .env.development                                                                  |    7 
 src/api/dnc.js                                                                    |   22 +
 src/views/dnc/base/modules/ProductStructure/ProductStructureMainTop.vue           |    4 
 package.json                                                                      |    1 
 .env.production                                                                   |    7 
 src/views/dnc/base/modules/ProductStructure/ProductStructureMainBottom.vue        |   60 ++++
 src/views/dnc/base/modules/ProductStructure/Document/FilePreview.vue              |   98 ++++++++
 18 files changed, 651 insertions(+), 53 deletions(-)

diff --git a/.env.development b/.env.development
new file mode 100644
index 0000000..baa73e5
--- /dev/null
+++ b/.env.development
@@ -0,0 +1,7 @@
+NODE_ENV=development
+# VUE_APP_API_BASE_URL=http://192.168.124.118:3000
+# VUE_APP_API_BASE_URL=http://195.0.1.10:6099
+VUE_APP_API_BASE_URL=http://192.168.124.26:9999
+# VUE_APP_API_BASE_URL=http://195.0.1.10:8099
+VUE_APP_CAS_BASE_URL=http://cas.example.org:8443/cas
+VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview
\ No newline at end of file
diff --git a/.env.production b/.env.production
new file mode 100644
index 0000000..870a556
--- /dev/null
+++ b/.env.production
@@ -0,0 +1,7 @@
+NODE_ENV=production
+# VUE_APP_API_BASE_URL=http://195.0.1.10:8099
+# VUE_APP_API_BASE_URL=http://195.0.1.10:6099
+# VUE_APP_API_BASE_URL=http://192.168.124.123:9999
+VUE_APP_API_BASE_URL=http://172.16.99.3:6099
+VUE_APP_CAS_BASE_URL=http://localhost:8888/cas
+VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview1p
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 6f3929c..8c3e438 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -569,6 +569,11 @@
         "@babel/types": "^7.10.4"
       }
     },
+    "@babel/helper-string-parser": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+      "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA=="
+    },
     "@babel/helper-validator-identifier": {
       "version": "7.10.4",
       "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
@@ -3534,6 +3539,56 @@
         }
       }
     },
+    "@vue/compiler-sfc": {
+      "version": "2.7.16",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-2.7.16.tgz",
+      "integrity": "sha512-KWhJ9k5nXuNtygPU7+t1rX6baZeqOYLEforUPjgNDBnLicfHCoi48H87Q8XyLZOrNNsmhuwKqtpDQWjEFe6Ekg==",
+      "requires": {
+        "@babel/parser": "^7.23.5",
+        "postcss": "^8.4.14",
+        "prettier": "^1.18.2 || ^2.0.0",
+        "source-map": "^0.6.1"
+      },
+      "dependencies": {
+        "@babel/helper-validator-identifier": {
+          "version": "7.25.9",
+          "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+          "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="
+        },
+        "@babel/parser": {
+          "version": "7.26.5",
+          "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.26.5.tgz",
+          "integrity": "sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==",
+          "requires": {
+            "@babel/types": "^7.26.5"
+          }
+        },
+        "@babel/types": {
+          "version": "7.26.5",
+          "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.5.tgz",
+          "integrity": "sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==",
+          "requires": {
+            "@babel/helper-string-parser": "^7.25.9",
+            "@babel/helper-validator-identifier": "^7.25.9"
+          }
+        },
+        "postcss": {
+          "version": "8.5.1",
+          "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.1.tgz",
+          "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==",
+          "requires": {
+            "nanoid": "^3.3.8",
+            "picocolors": "^1.1.1",
+            "source-map-js": "^1.2.1"
+          }
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+        }
+      }
+    },
     "@vue/component-compiler-utils": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.1.2.tgz",
@@ -3768,6 +3823,11 @@
       "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
       "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
       "dev": true
+    },
+    "abbrev": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/abbrev/-/abbrev-1.1.1.tgz",
+      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
     },
     "abs-svg-path": {
       "version": "0.1.1",
@@ -7539,6 +7599,11 @@
         }
       }
     },
+    "csstype": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
+      "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+    },
     "current-script-polyfill": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/current-script-polyfill/-/current-script-polyfill-1.0.0.tgz",
@@ -8037,6 +8102,34 @@
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
       "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw=="
+    },
+    "diff": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmmirror.com/diff/-/diff-3.5.0.tgz",
+      "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA=="
+    },
+    "diff2html": {
+      "version": "3.4.51",
+      "resolved": "https://registry.npmmirror.com/diff2html/-/diff2html-3.4.51.tgz",
+      "integrity": "sha512-/rVCSDyokkzSCEGaGjkkElXtIRwyNDRzIa3S8VUhR6pjk25p6+AMnb1s2zGmhjl66D5m/HnV3IeZoxnWsvTy+w==",
+      "requires": {
+        "diff": "^7.0.0",
+        "highlight.js": "11.9.0",
+        "hogan.js": "3.0.2"
+      },
+      "dependencies": {
+        "diff": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmmirror.com/diff/-/diff-7.0.0.tgz",
+          "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw=="
+        },
+        "highlight.js": {
+          "version": "11.9.0",
+          "resolved": "https://registry.npmmirror.com/highlight.js/-/highlight.js-11.9.0.tgz",
+          "integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==",
+          "optional": true
+        }
+      }
     },
     "diffie-hellman": {
       "version": "5.0.3",
@@ -10220,6 +10313,22 @@
         "minimalistic-crypto-utils": "^1.0.1"
       }
     },
+    "hogan.js": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmmirror.com/hogan.js/-/hogan.js-3.0.2.tgz",
+      "integrity": "sha512-RqGs4wavGYJWE07t35JQccByczmNUXQT0E12ZYV1VKYu5UiAU9lsos/yBAcf840+zrUQQxgVduCR5/B8nNtibg==",
+      "requires": {
+        "mkdirp": "0.3.0",
+        "nopt": "1.0.10"
+      },
+      "dependencies": {
+        "mkdirp": {
+          "version": "0.3.0",
+          "resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-0.3.0.tgz",
+          "integrity": "sha512-OHsdUcVAQ6pOtg5JYWpCBo9W/GySVuwvP9hueRMW7UqshC0tbfzLv8wjySTPm3tfUZ/21CE9E1pJagOA91Pxew=="
+        }
+      }
+    },
     "home-or-tmp": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
@@ -12294,6 +12403,11 @@
         "thenify-all": "^1.0.0"
       }
     },
+    "nanoid": {
+      "version": "3.3.8",
+      "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.8.tgz",
+      "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="
+    },
     "nanomatch": {
       "version": "1.2.13",
       "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -12445,6 +12559,14 @@
       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.59.tgz",
       "integrity": "sha512-H3JrdUczbdiwxN5FuJPyCHnGHIFqQ0wWxo+9j1kAXAzqNMAHlo+4I/sYYxpyK0irQ73HgdiyzD32oqQDcU2Osw==",
       "dev": true
+    },
+    "nopt": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmmirror.com/nopt/-/nopt-1.0.10.tgz",
+      "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
+      "requires": {
+        "abbrev": "1"
+      }
     },
     "normalize-package-data": {
       "version": "2.5.0",
@@ -13033,6 +13155,11 @@
       "version": "4.1.3",
       "resolved": "https://registry.npmjs.org/photoswipe/-/photoswipe-4.1.3.tgz",
       "integrity": "sha512-89Z43IRUyw7ycTolo+AaiDn3W1EEIfox54hERmm9bI12IB9cvRfHSHez3XhAyU8XW2EAFrC+2sKMhh7SJwn0bA=="
+    },
+    "picocolors": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
     },
     "picomatch": {
       "version": "2.2.2",
@@ -15976,6 +16103,11 @@
         "amdefine": ">=0.0.4"
       }
     },
+    "source-map-js": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
+      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="
+    },
     "source-map-resolve": {
       "version": "0.5.3",
       "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
@@ -17310,6 +17442,33 @@
       "resolved": "https://registry.npmmirror.com/vue-calendar-component/-/vue-calendar-component-2.8.2.tgz",
       "integrity": "sha512-BJh7xOBzM7QVcapcN4EbPQ1eZ8Pii1/oy+dzqjZTilRSIDD7SRPdFpnUJwZvs8lCrhtBAyJbYFsdm2SogXWHVQ=="
     },
+    "vue-code-diff": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/vue-code-diff/-/vue-code-diff-1.2.0.tgz",
+      "integrity": "sha512-kgSCl1Cr3I0u0z5DyJFbqQ1Hk7s9uBl7bfGwIn1X8f1xGmWdu4eRqfeOLTS0ut06VfGslaprXdaSvgn7YGDh0Q==",
+      "requires": {
+        "diff": "^3.5.0",
+        "diff2html": "^3.3.1",
+        "highlight.js": "^9.18.5",
+        "vue": "^2.6.12"
+      },
+      "dependencies": {
+        "highlight.js": {
+          "version": "9.18.5",
+          "resolved": "https://registry.npmmirror.com/highlight.js/-/highlight.js-9.18.5.tgz",
+          "integrity": "sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA=="
+        },
+        "vue": {
+          "version": "2.7.16",
+          "resolved": "https://registry.npmmirror.com/vue/-/vue-2.7.16.tgz",
+          "integrity": "sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==",
+          "requires": {
+            "@vue/compiler-sfc": "2.7.16",
+            "csstype": "^3.1.0"
+          }
+        }
+      }
+    },
     "vue-cropper": {
       "version": "0.5.4",
       "resolved": "https://registry.npmjs.org/vue-cropper/-/vue-cropper-0.5.4.tgz",
diff --git a/package.json b/package.json
index 8b1d652..e15155c 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,7 @@
     "vue": "^2.6.10",
     "vue-area-linkage": "^5.1.0",
     "vue-calendar-component": "^2.8.2",
+    "vue-code-diff": "^1.2.0",
     "vue-cropper": "^0.5.4",
     "vue-drag-resize": "^1.5.4",
     "vue-i18n": "^8.7.0",
diff --git a/src/api/dnc.js b/src/api/dnc.js
index 08f99d7..c165520 100644
--- a/src/api/dnc.js
+++ b/src/api/dnc.js
@@ -26,17 +26,25 @@
   // 鎸囨淳鏂囨。鍒拌澶�
   assignDocumentToDeviceApi: params => postAction('/nc/activit/assign/file/apply', params),
   // 涓嬭浇鏂囨。
-  downloadDocumentApi: ({ id, docName }) => downloadFile(`/nc/doc/download/${id}`, docName),
+  downloadDocumentApi: ({ docId, docName }) => downloadFile(`/nc/doc/download/${docId}`, docName),
   // 鏂囨。鍑哄簱
-  documentOutboundApi: ({ id, docName }) => requestGetDownLoad(`/nc/doc/pull/${id}`, docName),
+  documentOutboundApi: ({ docId, docName }) => requestGetDownLoad(`/nc/doc/pull/${docId}`, docName),
   // 鏂囨。鍙栨秷鍑哄簱
-  documentCancelOutboundApi: id => putAction(`/nc/doc/cancel/pull/${id}`),
+  documentCancelOutboundApi: docId => putAction(`/nc/doc/cancel/pull/${docId}`),
   // 鏂囨。鍏ュ簱
-  documentVersionUpdateApi: ({ id, formData }) => uploadAction(`/nc/doc/push/${id}`, formData),
+  documentVersionUpdateApi: ({ docId, formData }) => uploadAction(`/nc/doc/push/${docId}`, formData),
   // 鏂囨。鍙戝竷
-  documentPublishApi: id => putAction(`/nc/doc/publish/${id}`),
+  documentPublishApi: docId => putAction(`/nc/doc/publish/${docId}`),
   // 鏂囨。閲嶆柊鍙戝竷
-  documentRepublishApi: id => putAction(`/nc/doc/republish/${id}`),
+  documentRepublishApi: docId => putAction(`/nc/doc/republish/${docId}`),
   // 鏂囨。褰掓。
-  documentPigeonholeApi: id => putAction(`/nc/doc/pigeonhole/${id}`)
+  documentPigeonholeApi: docId => putAction(`/nc/doc/pigeonhole/${docId}`),
+  // 鑾峰彇鏂囦欢棰勮
+  getFilePreviewApi: docId => getAction(`/nc/doc/preview/${docId}`),
+  // 鑾峰彇PDF鏂囦欢棰勮
+  getPdfFilePreviewApi: docId => getAction(`/nc/doc/preview/pdf/${docId}`),
+  // 鎸囧畾褰撳墠鏂囨。鐗堟湰
+  appointCurrentDocumentVersionApi: fileId => putAction(`/nc/file/assign/version/${fileId}`),
+  // 鏂囨。姣斿
+  fileCompareApi: fileIdArray => getAction(`/nc/file/comparison/${fileIdArray[0]}/${fileIdArray[1]}`)
 }
\ No newline at end of file
diff --git a/src/utils/request.js b/src/utils/request.js
index 2abc6cb..9092e57 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -15,8 +15,7 @@
 //console.log("apiBaseUrl= ",apiBaseUrl)
 // 鍒涘缓 axios 瀹炰緥
 const service = axios.create({
-  baseURL: '/api',
-  // baseURL: apiBaseUrl, // api base_url
+  baseURL: apiBaseUrl, // api base_url
   timeout: 500000 // 璇锋眰瓒呮椂鏃堕棿
 })
 
diff --git a/src/views/dnc/base/modules/ProductStructure/Component/ComponentInfo.vue b/src/views/dnc/base/modules/ProductStructure/Component/ComponentInfo.vue
index c409cde..b9c1cf1 100644
--- a/src/views/dnc/base/modules/ProductStructure/Component/ComponentInfo.vue
+++ b/src/views/dnc/base/modules/ProductStructure/Component/ComponentInfo.vue
@@ -1,8 +1,8 @@
 <template>
   <a-descriptions bordered :size="size">
-    <a-descriptions-item label="閮ㄤ欢鍚嶇О">{{currentLevelDetails.componentName}}</a-descriptions-item>
-    <a-descriptions-item label="閮ㄤ欢浠e彿">{{currentLevelDetails.componentCode}}</a-descriptions-item>
-    <a-descriptions-item label="閮ㄤ欢鍨嬪彿	">{{currentLevelDetails.componentModel}}</a-descriptions-item>
+    <a-descriptions-item label="鍚嶇О">{{currentLevelDetails.componentName}}</a-descriptions-item>
+    <a-descriptions-item label="浠e彿">{{currentLevelDetails.componentCode}}</a-descriptions-item>
+    <a-descriptions-item label="鍨嬪彿	">{{currentLevelDetails.componentModel}}</a-descriptions-item>
     <a-descriptions-item label="鐗╂枡缂栫爜">{{currentLevelDetails.materielCode}}</a-descriptions-item>
     <a-descriptions-item label="鏉愭枡">{{currentLevelDetails.materielDesp}}</a-descriptions-item>
     <a-descriptions-item label="瑙勬牸	">{{currentLevelDetails.componentScale}}</a-descriptions-item>
diff --git a/src/views/dnc/base/modules/ProductStructure/Document/DocumentModalForm.vue b/src/views/dnc/base/modules/ProductStructure/Document/DocumentModalForm.vue
index 05c8692..804181d 100644
--- a/src/views/dnc/base/modules/ProductStructure/Document/DocumentModalForm.vue
+++ b/src/views/dnc/base/modules/ProductStructure/Document/DocumentModalForm.vue
@@ -101,7 +101,7 @@
                 })
                 that.$emit('ok')
               } else {
-                that.$notification.warning({
+                that.$notification.error({
                   message: '娑堟伅',
                   description: res.message
                 })
diff --git a/src/views/dnc/base/modules/ProductStructure/Document/DocumentVersionTableList.vue b/src/views/dnc/base/modules/ProductStructure/Document/DocumentVersionTableList.vue
index b909b4c..aeb3240 100644
--- a/src/views/dnc/base/modules/ProductStructure/Document/DocumentVersionTableList.vue
+++ b/src/views/dnc/base/modules/ProductStructure/Document/DocumentVersionTableList.vue
@@ -1,31 +1,38 @@
 <template>
-  <a-table :columns="columns" :data-source="dataSource" bordered :pagination="false" :size="size" rowKey="fileId">
-    <template slot="rowIndex" slot-scope="text,record,index">
-      <span :style="{color:setCurrentVersionColor(record.publishFlag)}">{{parseInt(index) + 1}}</span>
-    </template>
-    <template slot="fileName" slot-scope="text,record,index">
+  <div>
+    <a-table :columns="columns" :data-source="dataSource" bordered :pagination="false" :size="size" rowKey="fileId"
+             :customRow="customRow">
+      <template slot="rowIndex" slot-scope="text,record,index">
+        <span :style="{color:setCurrentVersionColor(record.publishFlag)}">{{parseInt(index) + 1}}</span>
+      </template>
+      <template slot="fileName" slot-scope="text,record,index">
       <span :style="{color:setCurrentVersionColor(record.publishFlag)}">
         {{text}}.{{record.fileSuffix}}
         <span v-if="record.publishFlag">[褰撳墠鐗堟湰]</span>
       </span>
-    </template>
-    <template slot="docVersion" slot-scope="text,record">
-      <span :style="{color:setCurrentVersionColor(record.publishFlag)}">{{text}}</span>
-    </template>
-    <template slot="fileSize" slot-scope="text,record">
-      <span :style="{color:setCurrentVersionColor(record.publishFlag)}">{{(text/1024).toFixed(2)}}KB</span>
-    </template>
-  </a-table>
+      </template>
+      <template slot="docVersion" slot-scope="text,record">
+        <span :style="{color:setCurrentVersionColor(record.publishFlag)}">{{text}}</span>
+      </template>
+      <template slot="fileSize" slot-scope="text,record">
+        <span :style="{color:setCurrentVersionColor(record.publishFlag)}">{{(text/1024).toFixed(2)}}KB</span>
+      </template>
+    </a-table>
+    <SelectFileCompareModal :dataSource="dataSource" :setCurrentVersionColor="setCurrentVersionColor"
+                            ref="selectFileCompareModalRef"/>
+  </div>
 </template>
 
 <script>
   import { JeecgListMixin } from '@/mixins/JeecgListMixin'
   import { getAction } from '@/api/manage'
+  import dncApi from '@/api/dnc'
+  import SelectFileCompareModal from './SelectFileCompareModal'
 
   export default {
     name: 'DocumentVersionTableList',
     mixins: [JeecgListMixin],
-    components: {},
+    components: { SelectFileCompareModal },
     props: {
       currentDocumentInfo: {
         type: Object
@@ -38,6 +45,7 @@
       return {
         disableMixinCreated: true,
         queryParams: {},
+        currentDocumentVersion: '',
         columns: [
           { title: '搴忓彿', dataIndex: 'rowIndex', width: 65, align: 'center', scopedSlots: { customRender: 'rowIndex' } },
           { title: '鏂囦欢鍚嶇О', dataIndex: 'fileName', align: 'center', scopedSlots: { customRender: 'fileName' } },
@@ -48,6 +56,9 @@
           list: '/nc/file/find/list'
         }
       }
+    },
+    created() {
+      this.$bus.$on('tableMenuItemMethodTrigger', this.triggerCorrespondingMethod)
     },
     methods: {
       loadData() {
@@ -65,6 +76,8 @@
         getAction(this.url.list, params).then((res) => {
           if (res.success) {
             this.dataSource = res.list
+            this.currentDocumentVersion = res.list.find(item => item.publishFlag).docVersion
+            console.log('currentDocumentVersion', this.currentDocumentVersion)
           } else {
             this.$message.warning(res.message)
           }
@@ -74,6 +87,60 @@
       },
 
       /**
+       * 鎸囧畾褰撳墠鏂囨。涓哄綋鍓嶇増鏈�
+       * @param fileId 鏂囦欢Id
+       */
+      handleFileAssign({ fileId }) {
+        const that = this
+        dncApi.appointCurrentDocumentVersionApi(fileId)
+          .then(res => {
+            if (res.success) {
+              that.$notification.success({
+                message: '娑堟伅',
+                description: res.message
+              })
+              const currentAssignDocumentVersion = that.dataSource.find(item => item.fileId === fileId).docVersion
+              // 濡傛灉褰撳墠鎸囧畾鐗堟湰鐨勭増鏈彿涓庡綋鍓嶇増鏈殑鐗堟湰鍙蜂竴鑷村垯涓嶉噸鏂板姞杞藉垪琛ㄥ苟涓斾笉閲嶆柊閲婃斁棰勮鎺ュ彛璋冨彇
+              if (that.currentDocumentVersion === currentAssignDocumentVersion) return
+              that.loadData()
+              that.$emit('releaseFilePreviewApi')
+            } else {
+              that.$notification.error({
+                message: '娑堟伅',
+                description: res.message
+              })
+            }
+          })
+          .catch(err => {
+            that.$notification.error({
+              message: '娑堟伅',
+              description: err.message
+            })
+          })
+      },
+
+      handleFileAddRelative(_, modalTitle) {
+        if (!this.$refs.selectFileCompareModalRef) return
+        this.$refs.selectFileCompareModalRef.visible = true
+        this.$refs.selectFileCompareModalRef.title = modalTitle
+      },
+
+      customRow(record) {
+        return {
+          on: {
+            contextmenu: event => {
+              event.preventDefault()
+              this.$emit('handleTableContextMenuOpen', Object.assign({ param: 'file' }, record))
+            }
+          }
+        }
+      },
+
+      triggerCorrespondingMethod({ methodName, level, modalTitle, tableRowInfo }) {
+        if (this[methodName]) this[methodName](tableRowInfo, modalTitle)
+      },
+
+      /**
        * 璁剧疆琛ㄦ牸涓负褰撳墠鐗堟湰鐨勬枃浠惰〃鏍艰棰滆壊鏍囪瘑
        * @param publishFlag 鏄惁涓哄綋鍓嶇増鏈�
        * @returns {string} 棰滆壊鏍囪瘑
diff --git a/src/views/dnc/base/modules/ProductStructure/Document/FileCompareModal.vue b/src/views/dnc/base/modules/ProductStructure/Document/FileCompareModal.vue
new file mode 100644
index 0000000..4cb7928
--- /dev/null
+++ b/src/views/dnc/base/modules/ProductStructure/Document/FileCompareModal.vue
@@ -0,0 +1,77 @@
+<template>
+  <a-modal width="100%" :visible="visible" :title="title" @cancel="visible=false" :footer="null" :maskClosable="false">
+    <a-row>
+      <a-col :span="12"><span class="file-version-text">鐗堟湰鍙凤細{{fileVersionArray[0]}}</span></a-col>
+      <a-col :span="12"><span class="file-version-text">鐗堟湰鍙凤細{{fileVersionArray[1]}}</span></a-col>
+    </a-row>
+    <div class="code-diff-container">
+      <CodeDiff :old-string="oldVersionContent" :new-string="newVersionContent" outputFormat="side-by-side"/>
+    </div>
+  </a-modal>
+</template>
+
+<script>
+  import CodeDiff from 'vue-code-diff'
+
+  export default {
+    name: 'FileCompareModal',
+    components: { CodeDiff },
+    props: {
+      fileDiffObject: {
+        type: Object
+      },
+      fileVersionArray: {
+        type: Array
+      }
+    },
+    watch: {
+      visible: {
+        handler(value) {
+          if (value) {
+            const { fileDiffObject } = this
+            let fileContent = ''
+            for (let key in fileDiffObject) {
+              if (fileDiffObject.hasOwnProperty(key)) {
+                fileDiffObject[key].forEach((content, index) => {
+                  fileContent += content
+                  if (index !== fileDiffObject[key].length - 1) {
+                    fileContent += '\n'
+                  }
+                })
+                if (key === 'first') {
+                  this.oldVersionContent = fileContent
+                  fileContent = ''
+                }
+                else this.newVersionContent = fileContent
+              }
+            }
+          }
+          else this.newVersionContent = this.oldVersionContent = ''
+        }
+      }
+    },
+    data() {
+      return {
+        visible: false,
+        title: '',
+        oldVersionContent: '',
+        newVersionContent: ''
+      }
+    },
+    methods: {}
+  }
+</script>
+
+<style scoped>
+  .file-version-text {
+    font-weight: bold;
+    font-size: 16px;
+    margin-left: 5%;
+  }
+
+  .code-diff-container {
+    height: 500px;
+    overflow: auto;
+    margin-top: 20px
+  }
+</style>
\ No newline at end of file
diff --git a/src/views/dnc/base/modules/ProductStructure/Document/FilePreview.vue b/src/views/dnc/base/modules/ProductStructure/Document/FilePreview.vue
new file mode 100644
index 0000000..64508bc
--- /dev/null
+++ b/src/views/dnc/base/modules/ProductStructure/Document/FilePreview.vue
@@ -0,0 +1,98 @@
+<template>
+  <a-spin :spinning="spinning" style="height: 100%">
+    <!--<template v-if="currentDocumentInfo.docSuffix==='pdf'">-->
+    <!--<iframe :src="pdfUrl" frameborder="0"-->
+    <!--style="width: 100%;height: calc(100% - 5px)"></iframe>-->
+    <!--</template>-->
+
+    <template>
+      <textarea id="ncFileInfo" style="resize:none;width:100%;height: 100%"></textarea>
+    </template>
+  </a-spin>
+</template>
+
+<script>
+  import dncApi from '@/api/dnc'
+
+  export default {
+    name: 'FilePreview',
+    components: {},
+    props: {
+      currentDocumentInfo: {
+        type: Object
+      }
+    },
+    data() {
+      return {
+        spinning: false,
+        pdfUrl: ''
+      }
+    },
+    methods: {
+      getFilePreviewByApi() {
+        const { docId, docSuffix } = this.currentDocumentInfo
+        console.log('currentDocumentInfo', this.currentDocumentInfo)
+        // if (docSuffix !== 'pdf') {
+        //   document.getElementById('ncFileInfo').innerHTML = ''
+        //   dncApi.getFilePreviewApi(docId)
+        //     .then(res => {
+        //       console.log('res----------------------------', res)
+        //       if (res.success && res.list) {
+        //         let str = ''
+        //         res.list.forEach((val, k) => {
+        //           str += val
+        //           if (k != res.list.length - 1) {
+        //             str += '\n'
+        //           }
+        //         })
+        //         document.getElementById('ncFileInfo').innerHTML = str
+        //       } else {
+        //         this.$notification.error({
+        //           message: '娑堟伅',
+        //           description: res.message
+        //         })
+        //       }
+        //     })
+        // } else {
+        //   dncApi.getPdfFilePreviewApi(docId)
+        //     .then(res => {
+        //       let url = window.URL.createObjectURL(new Blob([res], { type: 'application/zip' }))
+        //       this.pdfUrl = './static/pdf/web/viewer.html?file=' + encodeURIComponent(url)
+        //       console.log('url===========================', url)
+        //       console.log('pdfUrl===========================', this.pdfUrl)
+        //     })
+        // }
+        this.spinning = true
+        document.getElementById('ncFileInfo').innerHTML = ''
+        dncApi.getFilePreviewApi(docId)
+          .then(res => {
+            console.log('res----------------------------', res)
+            if (res.success && res.list) {
+              let str = ''
+              res.list.forEach((val, k) => {
+                str += val
+                if (k != res.list.length - 1) {
+                  str += '\n'
+                }
+              })
+              document.getElementById('ncFileInfo').innerHTML = str
+            } else {
+              this.$notification.error({
+                message: '娑堟伅',
+                description: res.message
+              })
+            }
+          })
+          .finally(() => {
+            this.spinning = false
+          })
+      },
+    }
+  }
+</script>
+
+<style scoped>
+  /deep/ .ant-spin-container {
+    height: 100%;
+  }
+</style>
\ No newline at end of file
diff --git a/src/views/dnc/base/modules/ProductStructure/Document/SelectFileCompareModal.vue b/src/views/dnc/base/modules/ProductStructure/Document/SelectFileCompareModal.vue
new file mode 100644
index 0000000..9c6b7cd
--- /dev/null
+++ b/src/views/dnc/base/modules/ProductStructure/Document/SelectFileCompareModal.vue
@@ -0,0 +1,134 @@
+<template>
+  <a-modal :title="title" :visible="visible" :width="700" @cancel="handleCloseModal" @ok="handleOpenCompareModal"
+           :maskClosable="false">
+    <a-table :dataSource="dataSource" :columns="columns" :pagination="false" bordered :scroll="{y:364}"
+             :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}" rowKey="fileId">
+      <template slot="rowIndex" slot-scope="text,record,index">
+        <span :style="{color:setCurrentVersionColor(record.publishFlag)}">{{parseInt(index) + 1}}</span>
+      </template>
+      <template slot="fileName" slot-scope="text,record,index">
+      <span :style="{color:setCurrentVersionColor(record.publishFlag)}">
+        {{text}}.{{record.fileSuffix}}
+        <span v-if="record.publishFlag">[褰撳墠鐗堟湰]</span>
+      </span>
+      </template>
+      <template slot="docVersion" slot-scope="text,record">
+        <span :style="{color:setCurrentVersionColor(record.publishFlag)}">{{text}}</span>
+      </template>
+    </a-table>
+
+    <FileCompareModal ref="fileCompareModalRef" :fileDiffObject="fileDiffObject" :fileVersionArray="fileVersionArray"/>
+  </a-modal>
+</template>
+
+<script>
+  import dncApi from '@/api/dnc'
+  import FileCompareModal from './FileCompareModal'
+
+  export default {
+    name: 'SelectFileCompareModal',
+    components: { FileCompareModal },
+    props: {
+      dataSource: {
+        type: Array
+      },
+      setCurrentVersionColor: {
+        type: Function
+      }
+    },
+    data() {
+      return {
+        visible: false,
+        title: '',
+        selectedRowKeys: [],
+        fileDiffObject: {},
+        fileVersionArray: [],
+        selectedFileInfo: {},
+        columns: [
+          { title: '搴忓彿', dataIndex: 'rowIndex', width: 65, align: 'center', scopedSlots: { customRender: 'rowIndex' } },
+          { title: '鏂囦欢鍚嶇О', dataIndex: 'fileName', align: 'center', scopedSlots: { customRender: 'fileName' } },
+          { title: '鐗堟湰鍙�', dataIndex: 'docVersion', align: 'center', scopedSlots: { customRender: 'docVersion' } }
+        ]
+      }
+    },
+    watch: {
+      visible: {
+        handler(value) {
+          this.$nextTick(() => {
+            const selectAllCheckboxNode = document.querySelector('.ant-table-selection-column .ant-table-selection')
+            if (value) {
+              if (this.dataSource.length > 2) selectAllCheckboxNode.style.display = 'none'
+              else selectAllCheckboxNode.style.display = 'block'
+            }
+          })
+        }
+      }
+    },
+    methods: {
+      onSelectChange(selectedRowKeys) {
+        if (selectedRowKeys.length < 3) this.selectedRowKeys = selectedRowKeys
+        else this.selectedRowKeys = selectedRowKeys.slice(-2)
+      },
+
+      handleOpenCompareModal() {
+        const { $confirm, $notification, selectedRowKeys, title, dataSource } = this
+        if (selectedRowKeys.length < 2) {
+          $notification.warning({
+            message: '娑堟伅',
+            description: '璇峰嬀閫変袱涓増鏈瘮瀵�'
+          })
+          return
+        }
+        const that = this
+        $confirm({
+          title: '鎻愮ず',
+          content: '纭鎻愪氦鍚楋紵',
+          okText: '纭',
+          cancelText: '鍙栨秷',
+          onOk: () => {
+            that.fileVersionArray = []
+            dncApi.fileCompareApi(selectedRowKeys)
+              .then(res => {
+                if (res.success) {
+                  $notification.success({
+                    message: '娑堟伅',
+                    description: res.message
+                  })
+                  that.fileDiffObject = res.data
+                  // 浼犻�掔粰瀛愮粍浠跺綋鍓嶉�変腑鐨勬枃浠剁増鏈彿
+                  selectedRowKeys.forEach(fileId => {
+                    const selectedFileVersion = dataSource.find(item => item.fileId === fileId).docVersion
+                    that.fileVersionArray.push(selectedFileVersion)
+                  })
+                  that.handleCloseModal()
+                  if (!that.$refs.fileCompareModalRef) return
+                  that.$refs.fileCompareModalRef.visible = true
+                  that.$refs.fileCompareModalRef.title = title
+                } else {
+                  $notification.error({
+                    message: '娑堟伅',
+                    description: res.message
+                  })
+                }
+              })
+              .catch(err => {
+                $notification.error({
+                  message: '娑堟伅',
+                  description: err.message
+                })
+              })
+          }
+        })
+      },
+
+      handleCloseModal() {
+        this.visible = false
+        this.selectedRowKeys = []
+      }
+    }
+  }
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/src/views/dnc/base/modules/ProductStructure/Product/ProductInfo.vue b/src/views/dnc/base/modules/ProductStructure/Product/ProductInfo.vue
index f8ea01c..d28dc8a 100644
--- a/src/views/dnc/base/modules/ProductStructure/Product/ProductInfo.vue
+++ b/src/views/dnc/base/modules/ProductStructure/Product/ProductInfo.vue
@@ -1,8 +1,8 @@
 <template>
   <a-descriptions bordered :size="size">
-    <a-descriptions-item label="浜у搧鍚嶇О">{{currentLevelDetails.productName}}</a-descriptions-item>
-    <a-descriptions-item label="浜у搧鍨嬪彿">{{currentLevelDetails.productModel}}</a-descriptions-item>
-    <a-descriptions-item label="浜у搧浠g爜	">{{currentLevelDetails.productNo}}</a-descriptions-item>
+    <a-descriptions-item label="鍚嶇О">{{currentLevelDetails.productName}}</a-descriptions-item>
+    <a-descriptions-item label="鍨嬪彿">{{currentLevelDetails.productModel}}</a-descriptions-item>
+    <a-descriptions-item label="浠g爜	">{{currentLevelDetails.productNo}}</a-descriptions-item>
     <a-descriptions-item label="鍒涘缓浜�">{{currentLevelDetails.createName}}</a-descriptions-item>
     <a-descriptions-item label="鍒涘缓鏃堕棿" :span="2">{{currentLevelDetails.createTime}}</a-descriptions-item>
     <a-descriptions-item label="淇敼浜�">{{currentLevelDetails.updateName}}</a-descriptions-item>
diff --git a/src/views/dnc/base/modules/ProductStructure/ProductStructureMainBottom.vue b/src/views/dnc/base/modules/ProductStructure/ProductStructureMainBottom.vue
index e5a321e..4d36158 100644
--- a/src/views/dnc/base/modules/ProductStructure/ProductStructureMainBottom.vue
+++ b/src/views/dnc/base/modules/ProductStructure/ProductStructureMainBottom.vue
@@ -1,11 +1,11 @@
 <template>
   <a-tabs style="height: 100%" v-model="activeTabKey" v-if="Object.keys(currentLevelInfo).length>0"
           @change="handleTabChange">
-    <a-tab-pane :key="1" tab="浜у搧灞炴��" v-if="currentLevelInfo.type===1">
+    <a-tab-pane :key="1" tab="灞炴�т俊鎭�" v-if="currentLevelInfo.type===1">
       <ProductInfo :currentLevelDetails="currentLevelInfo.entity" :size="containerSize"/>
     </a-tab-pane>
 
-    <a-tab-pane :key="1" tab="閮ㄤ欢灞炴��" v-if="currentLevelInfo.type===2">
+    <a-tab-pane :key="1" tab="灞炴�т俊鎭�" v-if="currentLevelInfo.type===2">
       <ComponentInfo :currentLevelDetails="currentLevelInfo.entity" :size="containerSize"/>
     </a-tab-pane>
 
@@ -27,11 +27,13 @@
       </a-tab-pane>
 
       <a-tab-pane :key="2" tab="棰勮">
-
+        <FilePreview ref="filePreviewRef" :currentDocumentInfo="currentLevelInfo"/>
       </a-tab-pane>
 
       <a-tab-pane :key="3" tab="鏂囨。鐗堟湰">
         <DocumentVersionTableList ref="documentVersionTableRef" :currentDocumentInfo="currentLevelInfo"
+                                  @handleTableContextMenuOpen="handleTableContextMenuOpen"
+                                  @releaseFilePreviewApi="releaseFilePreviewApi"
                                   :size="containerSize"/>
       </a-tab-pane>
 
@@ -40,6 +42,8 @@
                                        :size="containerSize"/>
       </a-tab-pane>
     </template>
+
+    <TableContextMenu :tableRowInfo="currentRightClickedTableRowInfo" ref="tableContextMenuRef"/>
   </a-tabs>
 </template>
 
@@ -52,10 +56,14 @@
   import DocumentVersionTableList from './Document/DocumentVersionTableList'
   import UseDocumentEquipmentTableList from './Document/UseNcDocumentEquipmentTableList'
   import ProcessStepInfo from './ProcessStep/ProcessStepInfo'
+  import FilePreview from './Document/FilePreview'
+  import TableContextMenu from '../../../common/TableContextMenu'
 
   export default {
     name: 'ProductStructureMainBottom',
     components: {
+      TableContextMenu,
+      FilePreview,
       ProcessStepInfo,
       UseDocumentEquipmentTableList,
       DocumentVersionTableList,
@@ -70,6 +78,7 @@
         activeTabKey: 1,
         containerSize: 'small',
         currentLevelInfo: {},
+        currentRightClickedTableRowInfo: {},
         hasLoadedDataTabKeyArray: []
       }
     },
@@ -81,7 +90,7 @@
     methods: {
       /**
        * 鎺ユ敹鏍戠粍浠朵互鍙婅〃鏍间紶鏉ョ殑褰撳墠閫変腑鎴栫偣鍑荤殑椤逛俊鎭�
-       * @param levelInfo
+       * @param levelInfo 褰撳墠灞傜骇淇℃伅
        */
       receiveCurrentLevelInfo(levelInfo) {
         this.currentLevelInfo = levelInfo
@@ -91,15 +100,50 @@
 
       handleTabChange(activeTabKey) {
         if (!this.hasLoadedDataTabKeyArray.includes(activeTabKey)) {
-          if (activeTabKey === 3) {
-            this.$nextTick(() => this.$refs.documentVersionTableRef.loadData())
-          } else if (activeTabKey === 4) {
-            this.$nextTick(() => this.$refs.useDocumentEquipmentTableRef.loadData())
+          switch (activeTabKey) {
+            case 2:
+              this.$nextTick(() => this.$refs.filePreviewRef.getFilePreviewByApi())
+              break
+            case 3:
+              this.$nextTick(() => this.$refs.documentVersionTableRef.loadData())
+              break
+            case 4:
+              this.$nextTick(() => this.$refs.useDocumentEquipmentTableRef.loadData())
+              break
+            default:
           }
+          // 闃绘鎺ュ彛鍦ㄥ悓涓�鏂囨。涓�娆$偣鍑诲唴澶氭瑙﹀彂
           this.hasLoadedDataTabKeyArray.push(activeTabKey)
         }
       },
 
+      // 閲婃斁鏂囦欢棰勮鎺ュ彛
+      releaseFilePreviewApi() {
+        // 濡傛灉宸茬粡棰勮杩囨鏂囨。锛屽彲鍦ㄦ鏂囨。褰撳墠鐗堟湰鍙戠敓鏀瑰彉鍚庡啀娆¢瑙堟柊鐗堟湰鍐呭
+        if (this.hasLoadedDataTabKeyArray.includes(2)) this.hasLoadedDataTabKeyArray = this.hasLoadedDataTabKeyArray.filter(item => item !== 2)
+      },
+
+      /**
+       * 鎺у埗鍙抽敭鑿滃崟寮�鍚�
+       * @param record 褰撳墠琛ㄦ牸琛屼俊鎭�
+       */
+      handleTableContextMenuOpen(record) {
+        this.currentRightClickedTableRowInfo = Object.assign({}, record)
+        this.$refs.tableContextMenuRef.currentMenuLevel = record.param
+        this.$refs.tableContextMenuRef.menuStyle.top = event.clientY + 'px'
+        this.$refs.tableContextMenuRef.menuStyle.left = event.clientX + 'px'
+        this.$refs.tableContextMenuRef.menuVisible = true
+        document.body.addEventListener('click', this.handleMenuClose)
+      },
+
+      /**
+       * 鎺у埗鍙抽敭鑿滃崟鐐瑰嚮鍏抽棴
+       */
+      handleMenuClose() {
+        this.$refs.tableContextMenuRef.menuVisible = false
+        document.body.removeEventListener('click', this.handleMenuClose)
+      },
+
       reloadMainBottomTableData(tableName) {
         if (this.$refs[tableName + 'TableRef']) this.$refs[tableName + 'TableRef'].loadData()
       }
diff --git a/src/views/dnc/base/modules/ProductStructure/ProductStructureMainTop.vue b/src/views/dnc/base/modules/ProductStructure/ProductStructureMainTop.vue
index 0847514..d53279f 100644
--- a/src/views/dnc/base/modules/ProductStructure/ProductStructureMainTop.vue
+++ b/src/views/dnc/base/modules/ProductStructure/ProductStructureMainTop.vue
@@ -92,7 +92,7 @@
       handleDownload() {
         const that = this
         const { docId, docName } = this.currentRightClickedTableRowInfo
-        dncApi.downloadDocumentApi({ id: docId, docName })
+        dncApi.downloadDocumentApi({ docId, docName })
           .then(res => {
             if (res && !res.success) {
               that.$notification.error({
@@ -122,7 +122,7 @@
           okText: '纭',
           cancelText: '鍙栨秷',
           onOk: () => {
-            dncApi.documentOutboundApi({ id: docId, docName })
+            dncApi.documentOutboundApi({ docId, docName })
               .then(res => {
                 console.log('res------------------', res)
                 if (res.success) {
diff --git a/src/views/dnc/common/ImportFileModal.vue b/src/views/dnc/common/ImportFileModal.vue
index d5d1af0..585022f 100644
--- a/src/views/dnc/common/ImportFileModal.vue
+++ b/src/views/dnc/common/ImportFileModal.vue
@@ -78,7 +78,7 @@
         this.isUploadMultiple = false
         console.log('tableRowInfo', tableRowInfo)
         this.uploadParams = Object.assign({}, {
-          id: tableRowInfo.docId,
+          docId: tableRowInfo.docId,
           attributionId: tableRowInfo.attributionId,
           docClassCode: tableRowInfo.param
         })
@@ -101,7 +101,7 @@
        * 鐐瑰嚮涓婁紶鑷虫湇鍔″櫒鎸夐挳鏃惰Е鍙�
        */
       handleUpload() {
-        const { fileList, $notification, isUploadMultiple, uploadParams, $bus } = this
+        const { fileList, $notification, isUploadMultiple, uploadParams, $bus, handleModalClose } = this
         this.uploading = true
         let uploadedFileCount = 0
         let uploadSuccessFileCount = 0
@@ -118,7 +118,7 @@
             params = Object.assign({}, { params: uploadParams, formData })
           } else {
             apiMethod = dncApi.documentVersionUpdateApi
-            params = Object.assign({}, { id: uploadParams.id, formData })
+            params = Object.assign({}, { docId: uploadParams.docId, formData })
           }
           apiMethod(params)
             .then(res => {
@@ -151,7 +151,7 @@
                   $bus.$emit('reloadDocumentListData', uploadParams)
                   if (!isUploadMultiple) {
                     $bus.$emit('reloadMainBottomTableData', 'documentVersion')
-                    this.visible = false //鏃犳硶杩炵画鍏ュ簱澶氫釜鐗堟湰鍥犳鍏ュ簱鎴愬姛鍚庡嵆鍙��鍑虹獥鍙�
+                    handleModalClose() //鏃犳硶杩炵画鍏ュ簱澶氫釜鐗堟湰鍥犳鍏ュ簱鎴愬姛鍚庡嵆鍙��鍑虹獥鍙�
                   }
                 }
                 this.uploading = false
diff --git a/src/views/dnc/common/TableContextMenu.vue b/src/views/dnc/common/TableContextMenu.vue
index 7890110..7b50a4b 100644
--- a/src/views/dnc/common/TableContextMenu.vue
+++ b/src/views/dnc/common/TableContextMenu.vue
@@ -83,8 +83,8 @@
           ],
           //鏂囦欢
           file: [
-            { label: '鎸囧畾褰撳墠鐗堟湰', code: 'file_assign', isCommonMethod: false },//鏂囦欢-鎸囧畾褰撳墠鐗堟湰
-            { label: '姣斿', code: 'file_add_relative', isCommonMethod: false }//姣斿
+            { label: '鎸囧畾褰撳墠鐗堟湰', code: 'file_assign', subMenu: [], icon: 'export', isCommonMethod: false },//鏂囦欢-鎸囧畾褰撳墠鐗堟湰
+            { label: '姣斿', code: 'file_add_relative', subMenu: [], icon: 'export', isCommonMethod: false }//姣斿
           ]
         }
       }
@@ -93,12 +93,12 @@
       menuItemClick({ item, key }) {
         const menuKeyArray = key.split('_')
         const menuArrayItem = this.defaultContextMenuList[this.tableRowInfo.param].find(item => item.code === key)
-        const subMenuArrayItem = this.defaultContextMenuList[this.tableRowInfo.param].find(item => item.subMenu.length > 0).subMenu.find(item => item.code === key)
         let isCommonMethod, modalTitle
         if (menuArrayItem) {
           isCommonMethod = menuArrayItem.isCommonMethod
           modalTitle = menuArrayItem.label
         } else {
+          const subMenuArrayItem = this.defaultContextMenuList[this.tableRowInfo.param].find(item => item.subMenu.length > 0).subMenu.find(item => item.code === key)
           isCommonMethod = subMenuArrayItem.isCommonMethod
           modalTitle = subMenuArrayItem.label
         }
diff --git a/vue.config.js b/vue.config.js
index d77ce88..07c53ce 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -108,13 +108,10 @@
        },*/
       /* 娉ㄦ剰锛歫eecgboot鍓嶇鍋氫簡鏀归�狅紝姝ゅ涓嶉渶瑕侀厤缃法鍩熷拰鍚庡彴鎺ュ彛锛堝彧闇�瑕佹敼.env鐩稿叧閰嶇疆鏂囦欢鍗冲彲锛�
           issues/3462 寰堝浜烘澶勫仛浜嗛厤缃紝瀵艰嚧鍒锋柊鍓嶇404闂锛岃涓�瀹氭敞鎰�*/
-      '/api': {
-        target: 'http://127.0.0.1:9999',
+      '/jeecg-boot': {
+        target: 'http://localhost:8080', // 璇锋眰鏈湴 闇�瑕乯eecg-boot鍚庡彴椤圭洰
         ws: false,
-        changeOrigin: true,
-        pathRewrite: {
-          '^/api': ''
-        }
+        changeOrigin: true
       }
     }
   },

--
Gitblit v1.9.3