From 7e4a5e17ccf849c0e93f59d7435fde6e7faffccb Mon Sep 17 00:00:00 2001 From: taoge1020 Date: Wed, 20 Aug 2025 19:21:52 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E7=AE=A1=E7=90=86=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.production | 2 +- src/api/design/volumeCatalog/index.ts | 14 + src/permission.ts | 2 +- src/plugins/index.ts | 2 + src/router/index.ts | 5 + src/utils/useFileDownload.js | 63 +++ src/views/design/Professional/index.vue | 73 ++- src/views/design/condition/comm/filePage.vue | 24 +- src/views/design/designChange/index.vue | 5 +- src/views/design/designChange/indexEdit.vue | 3 +- src/views/design/drawing/index.vue | 6 +- src/views/design/drawingreview/detailForm.vue | 1 + src/views/design/volumeCatalog/codeDetail.vue | 468 ++++++++++++++++++ .../design/volumeCatalog/comm/histroy.vue | 16 +- src/views/design/volumeCatalog/index.vue | 11 +- src/views/login.vue | 6 +- .../materialReceive/index.vue | 26 +- .../materialReceive/word/index.vue | 6 +- src/views/materials/purchaseDoc/index.vue | 3 + src/views/materials/purchaseDoc/indexEdit.vue | 2 +- src/views/register.vue | 2 +- 21 files changed, 632 insertions(+), 108 deletions(-) create mode 100644 src/utils/useFileDownload.js create mode 100644 src/views/design/volumeCatalog/codeDetail.vue diff --git a/.env.production b/.env.production index 299cce2..8870fdc 100644 --- a/.env.production +++ b/.env.production @@ -14,7 +14,7 @@ VITE_APP_MONITOR_ADMIN = '/admin/applications' VITE_APP_SNAILJOB_ADMIN = '/snail-job' # 生产环境 -VITE_APP_BASE_API = 'http://58.17.134.85:8899' +VITE_APP_BASE_API = 'http://xny.yj-3d.com:8899' # 是否在打包时开启压缩,支持 gzip 和 brotli VITE_BUILD_COMPRESS = gzip diff --git a/src/api/design/volumeCatalog/index.ts b/src/api/design/volumeCatalog/index.ts index 955d78c..c7c3a01 100644 --- a/src/api/design/volumeCatalog/index.ts +++ b/src/api/design/volumeCatalog/index.ts @@ -116,3 +116,17 @@ export const getileDetail = (id) => { method: 'get' }); }; +/** + * 获取二维码信息 + * @param query + */ +export const codeInfo = (id) => { + const config: any = { + url: '/design/volumeFile/codeInfo?id=' + id, + method: 'get' + }; + config.headers = { + Authorization: '1' + }; + return request(config); +}; diff --git a/src/permission.ts b/src/permission.ts index 9c632aa..9e4507a 100644 --- a/src/permission.ts +++ b/src/permission.ts @@ -18,7 +18,7 @@ const isWhiteList = (path: string) => { router.beforeEach(async (to, from, next) => { NProgress.start(); - if (to.path == '/indexEquipment' || to.path == '/materials/purchaseDoc/uploadCode') { + if (to.path == '/indexEquipment' || to.path == '/materials/purchaseDoc/uploadCode' || to.path == '/codeDetail') { next(); } else if (getToken()) { to.meta.title && useSettingsStore().setTitle(to.meta.title); diff --git a/src/plugins/index.ts b/src/plugins/index.ts index 6c5e0c3..7449bde 100644 --- a/src/plugins/index.ts +++ b/src/plugins/index.ts @@ -10,6 +10,7 @@ import { download as dl } from '@/utils/request'; import { useDict } from '@/utils/dict'; import { getConfigKey, updateConfigByKey } from '@/api/system/config'; import { parseTime, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi'; +import { downloadFile } from '@/utils/useFileDownload'; import { App } from 'vue'; @@ -40,4 +41,5 @@ export default function installPlugin(app: App) { app.config.globalProperties.selectDictLabel = selectDictLabel; app.config.globalProperties.selectDictLabels = selectDictLabels; app.config.globalProperties.animate = animate; + app.config.globalProperties.downloadFile = downloadFile; } diff --git a/src/router/index.ts b/src/router/index.ts index c51dbc2..a1c90aa 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -104,6 +104,11 @@ export const constantRoutes: RouteRecordRaw[] = [ component: () => import('@/views/materials/orderEquipment/indexEquipment.vue'), hidden: true }, + { + path: '/codeDetail', + component: () => import('@/views/design/volumeCatalog/codeDetail.vue'), + hidden: true + }, { path: '/drone', component: () => import('@/views/drone/index.vue'), diff --git a/src/utils/useFileDownload.js b/src/utils/useFileDownload.js new file mode 100644 index 0000000..473f846 --- /dev/null +++ b/src/utils/useFileDownload.js @@ -0,0 +1,63 @@ +import { ElMessage } from 'element-plus'; + +/** + * 下载文件下载工具函数 + * @param {string} fileUrl - 文件地址 + * @param {string} [fileName] - 可选,指定文件名 + * @param {Object} [headers] - 可选,请求头(如携带token) + */ +export const downloadFile = async (fileUrl, fileName, headers = {}) => { + try { + // 发起请求获取文件数据 + const response = await fetch(fileUrl, { + method: 'GET', + headers: { + 'Content-Type': 'application/octet-stream', + ...headers + }, + credentials: 'include' // 允许携带cookie + }); + + if (!response.ok) { + throw new Error(`下载失败: ${response.statusText}`); + } + + // 将响应转换为blob对象 + const blob = await response.blob(); + + // 创建临时URL + const url = URL.createObjectURL(blob); + + // 处理文件名 + let downloadName = fileName; + if (!downloadName) { + // 从响应头获取文件名 + const contentDisposition = response.headers.get('content-disposition'); + if (contentDisposition) { + const match = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/); + if (match && match[1]) { + downloadName = decodeURIComponent(match[1].replace(/['"]/g, '')); + } + } else { + // 从URL提取文件名 + downloadName = fileUrl.split('/').pop()?.split('?')[0] || 'download_file'; + } + } + + // 创建a标签并触发下载 + const link = document.createElement('a'); + link.href = url; + link.download = downloadName; + link.style.display = 'none'; // 隐藏a标签 + document.body.appendChild(link); + link.click(); + + // 清理资源 + setTimeout(() => { + document.body.removeChild(link); + URL.revokeObjectURL(url); // 释放临时URL + }, 100); + } catch (error) { + ElMessage.error(`文件下载失败: ${error.message}`); + } +}; diff --git a/src/views/design/Professional/index.vue b/src/views/design/Professional/index.vue index dc5ba89..bb795fe 100644 --- a/src/views/design/Professional/index.vue +++ b/src/views/design/Professional/index.vue @@ -35,46 +35,33 @@ - + - + - + + - - - @@ -131,6 +116,7 @@ const showSearch = ref(true); const loading = ref(false); const loadingFlie = ref(false); const viewVisible = ref(false); //文件列表展示 +const viewFlie = ref(''); const fileList = ref([]); const data = reactive({ queryParams: { @@ -205,10 +191,11 @@ const handleDownload = (row) => { ); }; const handleViewFile = (row) => { - window.open(row.docUrl, '_blank'); + window.open(row.fileUrl, '_blank'); }; const handleFile = async (row) => { // 查看文件 + viewFlie.value = row.status; viewVisible.value = true; loadingFlie.value = true; let res = await getFileList(row.id); diff --git a/src/views/design/condition/comm/filePage.vue b/src/views/design/condition/comm/filePage.vue index 0db8f8a..df3d89d 100644 --- a/src/views/design/condition/comm/filePage.vue +++ b/src/views/design/condition/comm/filePage.vue @@ -25,7 +25,7 @@ @@ -117,28 +117,12 @@ const onView = (row) => { } }); }; -const onExport = (fileUrl) => { - if (!fileUrl) { +const onExport = (row) => { + if (!row.fileUrl) { proxy.$modal.error('文件地址不存在,无法下载'); return; } - try { - // 创建一个隐藏的a标签 - const link = document.createElement('a'); - // 设置下载地址 - link.href = fileUrl; - // 从URL中提取文件名作为下载文件名 - const fileName = fileUrl.split('/').pop(); - link.download = fileName || 'download file'; - // 触发点击事件 - link.click(); - // 下载后移除a标签 - document.body.removeChild(link); - // 显示下载成功提示 - proxy.$modal.success('文件开始下载'); - } catch (error) { - // proxy.$modal.error('下载失败,请稍后重试'); - } + proxy.downloadFile(row.fileUrl, row.fileName); }; // 页面挂载时初始化数据 onMounted(() => { diff --git a/src/views/design/designChange/index.vue b/src/views/design/designChange/index.vue index 19fbc4c..1aa02bc 100644 --- a/src/views/design/designChange/index.vue +++ b/src/views/design/designChange/index.vue @@ -65,8 +65,9 @@ - - + + + - +