| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- <!-- 材料附件 -->
- <template>
- <view class="materialAttachments">
- <scroll-view scroll-y @scrolltolower="scrollGet" class="info-max-box">
- <view class="list">
- <view class="list-li" v-for="(item,index) in newData">
- <img :src="imagesUrl('safetyCheck/icon_djc_wj.png')">
- <view>{{item.fileName}}</view>
- <view @click="attachmentPreview(item)">查看</view>
- </view>
- </view>
- </scroll-view>
- </view>
- </template>
- <script>
- import {
- config
- } from '@/api/request/config.js'
- import {
- chemicalAppletGetStockDetail
- } from '@/pages/api/index.js'
- export default {
- name: "materialAttachments",
- components: {
- },
- data() {
- return {
- baseUrl: config.base_url,
- pageType: 0,
- newData: {},
- }
- },
- onLoad(option) {
- this.newData = JSON.parse(decodeURIComponent(option.infoData))
- },
- onShow() {
- },
- mounted() {
- },
- methods: {
- //滚动事件
- scrollGet() {},
- // 将此函数添加到 methods 中
- async attachmentPreview(item) {
- uni.showLoading({ title: '下载中' });
- const fileUrl = config.base_url + item.fileUrl;
-
- // #ifdef H5
- try {
- const response = await new Promise((resolve, reject) => {
- uni.request({
- url: fileUrl,
- method: 'GET',
- header: { Authorization: uni.getStorageSync('token') },
- responseType: 'arraybuffer', // 核心:使用 arraybuffer
- success: resolve,
- fail: reject,
- });
- });
- // 检查响应状态
- if (response.statusCode !== 200) {
- throw new Error(`下载失败,状态码: ${response.statusCode}`);
- }
- // 从 arraybuffer 创建 Blob 对象
- const blob = new Blob([response.data], {
- type: response.header['content-type'] || 'application/octet-stream'
- });
- const blobUrl = URL.createObjectURL(blob);
- const link = document.createElement('a');
- link.href = blobUrl;
- // 提取文件名
- let filename = this.getFileNameFromResponse(response, fileUrl);
- link.download = filename;
- document.body.appendChild(link);
- link.click();
- document.body.removeChild(link);
- URL.revokeObjectURL(blobUrl);
- uni.hideLoading();
- } catch (error) {
- console.error('下载失败:', error);
- uni.hideLoading();
- uni.showToast({ title: '下载失败', icon: 'none' });
- }
- // #endif
- // #ifdef MP-WEIXIN
- uni.downloadFile({
- url: config.base_url + item.fileUrl,
- header: {
- Authorization: uni.getStorageSync('token')
- },
- success: function(res) {
- uni.hideLoading();
- const filePath = res.tempFilePath
- wx.openDocument({
- filePath: filePath,
- success: function(res) {
- console.log('打开文档成功')
- }
- })
- },
- fail: function(res) {
- uni.hideLoading();
- uni.showToast({
- title: '下载失败',
- icon: "none",
- mask: true,
- duration: 2000
- });
- }
- })
- // #endif
- },
- // 辅助函数:从响应头或 URL 中解析文件名
- getFileNameFromResponse(response, fallbackUrl) {
- // 1. 从 Content-Disposition 响应头解析
- const contentDisposition = response.header['content-disposition'];
- if (contentDisposition) {
- // 匹配 filename*=UTF-8''encoded_filename 格式
- let match = contentDisposition.match(/filename\*=UTF-8''([^;]+)/i);
- if (match && match[1]) {
- return decodeURIComponent(match[1]);
- }
- // 匹配 filename="filename.pdf" 格式
- match = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/i);
- if (match && match[1]) {
- let filename = match[1].replace(/['"]/g, '');
- try {
- return decodeURIComponent(filename);
- } catch (e) {
- return filename;
- }
- }
- }
- // 2. 后备方案:从 URL 中提取
- let urlParts = fallbackUrl.split('/');
- let filename = urlParts[urlParts.length - 1].split('?')[0];
- // 3. 如果 URL 中也没有文件名,则根据 MIME 类型生成默认名
- if (!filename || filename === '') {
- const mimeToExt = {
- 'application/pdf': '.pdf',
- 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': '.xlsx',
- 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': '.docx',
- };
- const contentType = response.header['content-type'];
- const extension = mimeToExt[contentType] || '.bin';
- filename = `download_${Date.now()}${extension}`;
- }
- return filename;
- },
- // attachmentPreview(item) {
- // uni.showLoading({
- // title: '下载中'
- // });
- // uni.downloadFile({
- // url: config.base_url + item.fileUrl,
- // header: {
- // Authorization: uni.getStorageSync('token')
- // },
- // success: function(res) {
- // uni.hideLoading();
- // // #ifdef MP-WEIXIN
- // const filePath = res.tempFilePath
- // wx.openDocument({
- // filePath: filePath,
- // success: function(res) {
- // console.log('打开文档成功')
- // }
- // })
- // // #endif
- // },
- // fail: function(res) {
- // uni.hideLoading();
- // uni.showToast({
- // title: '下载失败',
- // icon: "none",
- // mask: true,
- // duration: 2000
- // });
- // }
- // })
- // },
- }
- }
- </script>
- <style lang="stylus" scoped>
- .materialAttachments {
- height: 100%;
- display flex;
- box-sizing: border-box;
- padding: 0 30rpx;
- box-sizing: border-box;
-
- .list {
- width: 690rpx;
- background: #FFFFFF;
- border-radius: 20rpx 20rpx 20rpx 20rpx;
- padding: 0 30rpx;
- box-sizing: border-box;
- margin-bottom: 20rpx;
- margin-top: 20rpx;
- .list-li {
- height: 100rpx;
- border-bottom: 1rpx solid #E0E0E0;
- display: flex;
- justify-content: space-between;
- align-items: center;
- >img {
- width: 30rpx;
- height: 30rpx;
- margin-right: 16rpx;
- }
- >view:nth-of-type(1) {
- flex: 1;
- font-size: 28rpx;
- color: #333333;
- line-height: 39rpx;
- text-align: left;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- margin-right: 56rpx;
- }
- >view:nth-of-type(2) {
- font-size: 28rpx;
- color: #0183FA;
- line-height: 39rpx;
- text-align: left;
- }
- }
- .list-li:last-of-type {
- border: none;
- }
- }
- }
- </style>
|