|
|
|
|
@ -8,6 +8,7 @@ import {
|
|
|
|
|
reviewApplicationSubmitScoreUrl,
|
|
|
|
|
} from '../../config/api'
|
|
|
|
|
import { ElMessage } from 'element-plus'
|
|
|
|
|
import { beginDownloadFeedback, notifyDownloadStarted } from '../../utils/downloadFeedback'
|
|
|
|
|
import { Modal } from 'bootstrap'
|
|
|
|
|
import ApplicationSignupDetailFields from '../../components/portal/ApplicationSignupDetailFields.vue'
|
|
|
|
|
import {
|
|
|
|
|
@ -329,7 +330,13 @@ function goBack() {
|
|
|
|
|
void router.push({ name: 'reviewer-projects', params: { slug: s }, query })
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const downloadingFileId = ref<number | null>(null)
|
|
|
|
|
|
|
|
|
|
async function downloadAttachment(f: FileItem) {
|
|
|
|
|
if (downloadingFileId.value != null) {
|
|
|
|
|
ElMessage.warning('附件正在下载中,请勿重复点击')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
const id = applicationId.value
|
|
|
|
|
const s = slug.value
|
|
|
|
|
const { token } = readReviewerSession()
|
|
|
|
|
@ -337,6 +344,11 @@ async function downloadAttachment(f: FileItem) {
|
|
|
|
|
ElMessage.warning('未登录或参数无效')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
const fileName = f.original_name?.trim() || '附件'
|
|
|
|
|
const feedback = beginDownloadFeedback(fileName, f.size)
|
|
|
|
|
if (!feedback) return
|
|
|
|
|
|
|
|
|
|
downloadingFileId.value = f.id
|
|
|
|
|
const url = reviewApplicationFileDownloadUrl(parseInt(id, 10), f.id, s)
|
|
|
|
|
try {
|
|
|
|
|
const r = await fetch(url, {
|
|
|
|
|
@ -355,18 +367,23 @@ async function downloadAttachment(f: FileItem) {
|
|
|
|
|
ElMessage.error(message)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
feedback.setText(`正在保存「${fileName}」…`)
|
|
|
|
|
const blob = await r.blob()
|
|
|
|
|
const objectUrl = URL.createObjectURL(blob)
|
|
|
|
|
const a = document.createElement('a')
|
|
|
|
|
a.href = objectUrl
|
|
|
|
|
a.download = f.original_name?.trim() ? f.original_name : 'download'
|
|
|
|
|
a.download = fileName === '附件' ? 'download' : fileName
|
|
|
|
|
a.rel = 'noopener'
|
|
|
|
|
document.body.appendChild(a)
|
|
|
|
|
a.click()
|
|
|
|
|
a.remove()
|
|
|
|
|
URL.revokeObjectURL(objectUrl)
|
|
|
|
|
notifyDownloadStarted()
|
|
|
|
|
} catch {
|
|
|
|
|
ElMessage.error('网络错误,无法下载')
|
|
|
|
|
} finally {
|
|
|
|
|
feedback.close()
|
|
|
|
|
downloadingFileId.value = null
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -531,8 +548,18 @@ async function submitReviewScore() {
|
|
|
|
|
v-if="planFile"
|
|
|
|
|
class="form-control-plaintext border rounded px-3 py-2 mb-0 bg-light small text-secondary"
|
|
|
|
|
>
|
|
|
|
|
<a role="button" href="#" class="text-danger text-decoration-none" @click.prevent="downloadAttachment(planFile)">
|
|
|
|
|
{{ planFile.original_name }}
|
|
|
|
|
<a
|
|
|
|
|
role="button"
|
|
|
|
|
href="#"
|
|
|
|
|
class="text-danger text-decoration-none"
|
|
|
|
|
:class="{ 'pe-none opacity-75': downloadingFileId != null }"
|
|
|
|
|
@click.prevent="downloadAttachment(planFile)"
|
|
|
|
|
>
|
|
|
|
|
{{
|
|
|
|
|
downloadingFileId === planFile.id
|
|
|
|
|
? `下载中… ${planFile.original_name}`
|
|
|
|
|
: planFile.original_name
|
|
|
|
|
}}
|
|
|
|
|
</a>
|
|
|
|
|
</p>
|
|
|
|
|
<p v-else class="form-control-plaintext border rounded px-3 py-2 mb-0 bg-light small text-secondary">—</p>
|
|
|
|
|
@ -541,9 +568,16 @@ async function submitReviewScore() {
|
|
|
|
|
<label class="form-label">其他佐证材料</label>
|
|
|
|
|
<ul v-if="supportingFiles.length" class="list-unstyled mb-0 border rounded px-3 py-2 bg-light small">
|
|
|
|
|
<li v-for="f in supportingFiles" :key="f.id">
|
|
|
|
|
<a role="button" href="#" class="text-danger text-decoration-none" @click.prevent="downloadAttachment(f)">{{
|
|
|
|
|
f.original_name
|
|
|
|
|
}}</a>
|
|
|
|
|
<a
|
|
|
|
|
role="button"
|
|
|
|
|
href="#"
|
|
|
|
|
class="text-danger text-decoration-none"
|
|
|
|
|
:class="{ 'pe-none opacity-75': downloadingFileId != null }"
|
|
|
|
|
@click.prevent="downloadAttachment(f)"
|
|
|
|
|
>{{
|
|
|
|
|
downloadingFileId === f.id ? `下载中… ${f.original_name}` : f.original_name
|
|
|
|
|
}}</a
|
|
|
|
|
>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
<p v-else class="form-control-plaintext border rounded px-3 py-2 mb-0 bg-light small text-secondary">—</p>
|
|
|
|
|
|