fix: support sms signature file download
This commit is contained in:
@@ -288,8 +288,17 @@
|
||||
</div>
|
||||
<div class="detail-file-row">
|
||||
<span class="detail-img-label">申请文件</span>
|
||||
<el-link v-if="detailData.application_file_url" type="primary" :href="detailData.application_file_url" target="_blank">查看申请文件</el-link>
|
||||
<span v-else class="detail-empty-text">未上传</span>
|
||||
<el-button
|
||||
v-if="getApplicationFileUrl(detailData)"
|
||||
link
|
||||
type="primary"
|
||||
:loading="applicationFileDownloading"
|
||||
@click="downloadApplicationFile(detailData)"
|
||||
>
|
||||
<el-icon v-if="!applicationFileDownloading"><Download /></el-icon>
|
||||
下载申请文件
|
||||
</el-button>
|
||||
<span v-else class="detail-empty-text">暂无可下载文件</span>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
@@ -314,8 +323,9 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import axios from 'axios'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Plus, User, Close, Picture } from '@element-plus/icons-vue'
|
||||
import { Plus, User, Close, Picture, Download } from '@element-plus/icons-vue'
|
||||
import { formatDate } from '@/utils/tool'
|
||||
import {
|
||||
getSmsServiceList,
|
||||
@@ -392,6 +402,7 @@ const currentRow = ref(null)
|
||||
|
||||
const detailVisible = ref(false)
|
||||
const detailData = ref(null)
|
||||
const applicationFileDownloading = ref(false)
|
||||
|
||||
const userSelectorVisible = ref(false)
|
||||
const selectedUserInfo = ref(null)
|
||||
@@ -466,6 +477,83 @@ const handleDetail = (row) => {
|
||||
detailVisible.value = true
|
||||
}
|
||||
|
||||
const getSignatureService = (row) => {
|
||||
const serviceId = row.service_id || queryParams.service_id
|
||||
return serviceOptions.value.find(item => String(item.id) === String(serviceId))
|
||||
}
|
||||
|
||||
const getApplicationFileUrl = (row) => {
|
||||
if (!row?.ID || !row?.application_file_url) return ''
|
||||
const service = getSignatureService(row)
|
||||
const endpoint = String(service?.host || '').replace(/\/+$/, '')
|
||||
if (!endpoint) return ''
|
||||
return `${endpoint}/api/sms/admin/signature/${row.ID}/application-file`
|
||||
}
|
||||
|
||||
const getDownloadFilename = (headers, signatureId) => {
|
||||
const disposition = headers?.['content-disposition'] || ''
|
||||
const utf8Match = disposition.match(/filename\*=UTF-8''([^;]+)/i)
|
||||
const plainMatch = disposition.match(/filename="?([^";]+)"?/i)
|
||||
const encodedName = utf8Match?.[1] || plainMatch?.[1]
|
||||
if (!encodedName) return `签名申请文件_${signatureId}.xlsx`
|
||||
try {
|
||||
return decodeURIComponent(encodedName)
|
||||
} catch {
|
||||
return encodedName
|
||||
}
|
||||
}
|
||||
|
||||
const downloadApplicationFile = async (row) => {
|
||||
const url = getApplicationFileUrl(row)
|
||||
if (!url || applicationFileDownloading.value) return
|
||||
|
||||
const service = getSignatureService(row)
|
||||
const endpoint = String(service?.host || '').replace(/\/+$/, '')
|
||||
const serviceToken = service?.serviceToken || service?.service_token
|
||||
if (!serviceToken) {
|
||||
ElMessage.error('当前短信平台未配置 Service Token')
|
||||
return
|
||||
}
|
||||
|
||||
applicationFileDownloading.value = true
|
||||
try {
|
||||
const loginResponse = await axios.post(
|
||||
`${endpoint}/api/auth/service-token-login`,
|
||||
{ service_token: serviceToken },
|
||||
{ timeout: 15000 }
|
||||
)
|
||||
const loginBody = loginResponse.data || {}
|
||||
const platformToken = loginBody.data?.token
|
||||
if (loginBody.code !== 200 || !platformToken) {
|
||||
throw new Error(loginBody.message || '短信平台 Token 获取失败')
|
||||
}
|
||||
|
||||
const response = await axios.get(url, {
|
||||
headers: { Authorization: `Bearer ${platformToken}` },
|
||||
responseType: 'blob',
|
||||
timeout: 60000
|
||||
})
|
||||
const contentType = response.headers?.['content-type'] || ''
|
||||
if (contentType.includes('application/json')) {
|
||||
const body = JSON.parse(await response.data.text())
|
||||
throw new Error(body.message || body.msg || '下载申请文件失败')
|
||||
}
|
||||
|
||||
const objectUrl = window.URL.createObjectURL(response.data)
|
||||
const link = document.createElement('a')
|
||||
link.href = objectUrl
|
||||
link.download = getDownloadFilename(response.headers, row.ID)
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
link.remove()
|
||||
window.URL.revokeObjectURL(objectUrl)
|
||||
} catch (error) {
|
||||
ElMessage.error(error.message || '下载申请文件失败')
|
||||
} finally {
|
||||
applicationFileDownloading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleAdd = () => {
|
||||
dialogType.value = 'add'
|
||||
selectedUserInfo.value = null
|
||||
|
||||
Reference in New Issue
Block a user