huangxw пре 5 дана
родитељ
комит
5edb129f77

+ 1 - 2
src/plant/code/code-list/index.vue

@@ -57,7 +57,6 @@
 
 <script setup lang="ts">
 import { useClientRequest } from '@/utils/request';
-import { exportDataFn } from '@/utils/upload';
 import CodeItem from './models/code-item.vue';
 import GenerateDialog from './models/generate-dialog.vue';
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@@ -153,7 +152,7 @@ const handleDownload = async (item: any) => {
     }
     try {
         const downloadUrl = `/plt-api/app/traceCodeLog/download/${item.id}`;
-        await exportDataFn(
+        await useClientRequest.down(
             {
                 url: downloadUrl,
                 fileName: `traceCode_${item.id}.xlsx`,

+ 15 - 16
src/plant/export-print/models/export-print-confirm.vue

@@ -3,23 +3,15 @@
         <up-form class="p-rtv bg-#fff" labelPosition="top" :model="form" errorType="toast" :rules="rules" labelWidth="auto" ref="upFormUpRef">
             <view class="f-s-24 c-#999">导出追溯码仅支持导出追溯码地址用于喷印或排版好追溯码PDF文件直接打印。如有疑问,请。如有疑问,请<span class="c-primary">点击此处联系客服</span>。</view>
             <slot name="fileType"></slot>
-            <template v-if="opts.id">
+            <ut-action-sheet v-model="form.extraInfo.fileType" :tabs="pt_code_export_type" @change="changeExtraFileType" mode="custom" title="请选择导出类型">
                 <up-form-item borderBottom label="导出类型" required prop="extraInfo.fileType">
                     <view v-if="form.extraInfo?.fileType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_code_export_type, form.extraInfo.fileType) }}</view>
                     <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择导出类型</view>
+                    <template #right>
+                        <up-icon size="22rpx" color="#37A954" name="arrow-down-fill"></up-icon>
+                    </template>
                 </up-form-item>
-            </template>
-            <template v-else>
-                <ut-action-sheet v-model="form.extraInfo.fileType" :tabs="pt_code_export_type" @change="changeExtraFileType" mode="custom" title="请选择导出类型">
-                    <up-form-item borderBottom label="导出类型" required prop="extraInfo.fileType">
-                        <view v-if="form.extraInfo?.fileType" class="f-s-30 c-333 f-w-5 flex1">{{ selectDictLabel(pt_code_export_type, form.extraInfo.fileType) }}</view>
-                        <view v-else class="f-s-30 c-ccc f-w-4 flex1">请选择导出类型</view>
-                        <template #right>
-                            <up-icon size="22rpx" color="#37A954" name="arrow-down-fill"></up-icon>
-                        </template>
-                    </up-form-item>
-                </ut-action-sheet>
-            </template>
+            </ut-action-sheet>
 
             <template v-if="form.extraInfo.fileType == '2'">
                 <slot name="logos"></slot>
@@ -262,12 +254,19 @@ const submitForm = async () => {
     };
     const res = props.opts?.id ? await useClientRequest.post(`/plt-api/app/printLog/update/${props.opts.id}`, payload?.extraInfo) : await useClientRequest.post('/plt-api/app/printLog/printNext', payload);
     if (!res || res.code !== 200) return;
-    console.log(res);
-    
     uni.$emit('refreshPackTaskList');
     uni.$emit('refreshPackTaskDetail');
-    await useClientRequest.get(`/plt-api/app/printLog/export/${res.data?.id || props.opts?.id}`);
     uni.hideLoading();
+    if (payload.extraInfo.fileType === '1') {
+        await useClientRequest.down(
+            {
+                url: `/plt-api/app/printLog/export/${res.data?.id || props.opts?.id}`,
+            },
+            '正在导出...',
+        );
+    } else {
+        await useClientRequest.get(`/plt-api/app/printLog/exportLayout/${res.data?.id || props.opts?.id}`);
+    }
     uni.showToast({
         title: '导出成功',
         icon: 'success',

+ 109 - 0
src/utils/request.ts

@@ -1,4 +1,5 @@
 import config from '@/config';
+import { tansParams } from '@/utils/common';
 import { useInfoStore } from '@/store';
 import { getCurrentPage } from '@/utils/public';
 import { recursiveDecodeURIComponent } from '@/utils/ruoyi';
@@ -7,6 +8,14 @@ const { clientId, appid } = config;
 // uniapp封装的请求方法
 let timeout = 60 * 1000;
 
+interface ClientDownloadConfig {
+    url: string;
+    fileName?: string;
+    params?: Record<string, any>;
+    timeout?: number;
+    header?: Record<string, any>;
+}
+
 // 获取全局请求头方法
 const getHeader = () => {
     let header = {
@@ -18,6 +27,103 @@ const getHeader = () => {
     return header;
 };
 
+const getFileType = (url: string, result?: { header?: Record<string, any> }): string => {
+    if (url) {
+        const filenameFromUrl = url.split('/').pop();
+        const urlExt = filenameFromUrl?.includes('.') ? filenameFromUrl.split('.').pop()?.split(/[?#]/)[0] : null;
+        if (urlExt) return urlExt.toLowerCase() || 'pdf';
+    }
+
+    if (result?.header?.['content-disposition']) {
+        try {
+            const disposition = result.header['content-disposition'];
+            const filenameMatch = disposition.match(/filename\*?=(?:UTF-8''|")?([^;"\n]*)/i);
+
+            if (filenameMatch && filenameMatch[1]) {
+                const filename = filenameMatch[1].replace(/['"]/g, '');
+                if (filename.includes('.')) {
+                    const ext = filename.split('.').pop()?.split(/[?#]/)[0];
+                    return ext?.toLowerCase() || 'pdf';
+                }
+            }
+        } catch (e) {
+            console.warn('解析 Content-Disposition 失败:', e);
+        }
+    }
+
+    return 'pdf';
+};
+
+const buildDownloadUrl = (url: string, params?: Record<string, any>) => {
+    const isFullUrl = url.startsWith('http://') || url.startsWith('https://');
+    let downloadUrl = (isFullUrl ? '' : import.meta.env.VITE_API_BASE_URL || 'http://192.168.1.26:8080') + url;
+
+    if (params && Object.keys(params).length) {
+        const query = tansParams(params).slice(0, -1);
+        if (query) {
+            downloadUrl += `${downloadUrl.includes('?') ? '&' : '?'}${query}`;
+        }
+    }
+
+    return downloadUrl;
+};
+
+const download = (downloadConfig: ClientDownloadConfig, showTitle?: string): Promise<void> =>
+    new Promise((resolve, reject) => {
+        const downloadUrl = buildDownloadUrl(downloadConfig.url, downloadConfig.params);
+
+        uni.showLoading({
+            title: showTitle || '正在导出数据...',
+            mask: true,
+        });
+
+        uni.downloadFile({
+            url: downloadUrl,
+            timeout: downloadConfig.timeout || timeout,
+            header: {
+                ...getHeader(),
+                ...downloadConfig.header,
+            },
+            success: (res) => {
+                console.log(res);
+                
+                uni.hideLoading();
+                if (res.statusCode === 200) {
+                    uni.openDocument({
+                        filePath: res.tempFilePath,
+                        showMenu: true,
+                        fileType: getFileType(downloadConfig.fileName || downloadConfig.url, res as any) as any,
+                        success: () => {
+                            resolve();
+                        },
+                        fail: (err) => {
+                            uni.showToast({
+                                title: '打开文件失败',
+                                icon: 'none',
+                            });
+                            reject(err);
+                        },
+                    });
+                    return;
+                }
+
+                uni.showToast({
+                    title: '下载失败',
+                    icon: 'none',
+                });
+                reject(res);
+            },
+            fail: (error) => {
+                uni.hideLoading();
+                uni.showToast({
+                    title: '下载失败',
+                    icon: 'none',
+                });
+                reject(error);
+            },
+        });
+    });
+
 // 获取host地址
 export const request = ({ url, method = 'GET', data = {}, isToken = true, header = null }: any) => {
     const baseUrl = import.meta.env.VITE_API_BASE_URL || 'http://192.168.1.26:8080';
@@ -157,4 +263,7 @@ export const useClientRequest = {
             isToken,
         }) as Promise<T>;
     },
+    down: (config: ClientDownloadConfig, showTitle?: string): Promise<void> => {
+        return download(config, showTitle);
+    },
 };