fix(admin): 通过API端点下载简历附件,解决HTML问题

This commit is contained in:
TianyangZhang 2026-03-25 16:35:43 +08:00
parent a6ebd3af87
commit 79706dd840
2 changed files with 46 additions and 11 deletions

View File

@ -1,4 +1,7 @@
from rest_framework import generics, viewsets from rest_framework import generics, viewsets
from rest_framework.response import Response
from rest_framework.decorators import action
from django.http import FileResponse
from .models import Application from .models import Application
from .serializers import ApplicationCreateSerializer, ApplicationSerializer, ApplicationStatusSerializer from .serializers import ApplicationCreateSerializer, ApplicationSerializer, ApplicationStatusSerializer
from .emails import notify_status_change from .emails import notify_status_change
@ -28,6 +31,26 @@ class ApplicationManageViewSet(viewsets.ReadOnlyModelViewSet):
job__organization=user.organization job__organization=user.organization
).select_related('job__organization', 'applicant') ).select_related('job__organization', 'applicant')
@action(detail=True, methods=['get'])
def download_resume(self, request, pk=None):
"""下载求职者的简历附件"""
application = self.get_object()
attachment_url = application.resume_snapshot.get('attachment_url')
if not attachment_url:
return Response({'detail': '附件不可用'}, status=404)
try:
from django.core.files.storage import default_storage
# 获取文件
file = default_storage.open(attachment_url.lstrip('/media/'), 'rb')
response = FileResponse(file)
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = f'attachment; filename="{application.resume_snapshot.get("name", "resume")}.pdf"'
return response
except Exception as e:
return Response({'detail': f'下载失败: {str(e)}'}, status=400)
class ApplicationStatusUpdateView(generics.UpdateAPIView): class ApplicationStatusUpdateView(generics.UpdateAPIView):
serializer_class = ApplicationStatusSerializer serializer_class = ApplicationStatusSerializer
permission_classes = [IsAdminOrSuperAdmin] permission_classes = [IsAdminOrSuperAdmin]

View File

@ -104,6 +104,7 @@ const applications = ref([])
const loading = ref(false) const loading = ref(false)
const resumeVisible = ref(false) const resumeVisible = ref(false)
const currentResume = ref(null) const currentResume = ref(null)
const currentApplicationId = ref(null)
const genderMap = { const genderMap = {
'male': '男', 'male': '男',
@ -128,6 +129,7 @@ async function updateStatus(row) {
function viewResume(row) { function viewResume(row) {
currentResume.value = row.resume_snapshot currentResume.value = row.resume_snapshot
currentApplicationId.value = row.id
resumeVisible.value = true resumeVisible.value = true
} }
@ -135,19 +137,29 @@ function getGenderLabel(gender) {
return genderMap[gender] || '-' return genderMap[gender] || '-'
} }
function downloadAttachment() { async function downloadAttachment() {
if (!currentResume.value?.attachment_url) { if (!currentApplicationId.value) {
ElMessage.warning('附件不可用') ElMessage.warning('无法获取投递记录')
return return
} }
const link = document.createElement('a') try {
link.href = currentResume.value.attachment_url const response = await fetch(`/api/applications/manage/${currentApplicationId.value}/download_resume/`)
link.download = `${currentResume.value.name}_resume` if (!response.ok) throw new Error('下载失败')
link.style.display = 'none'
document.body.appendChild(link) const blob = await response.blob()
link.click() const url = window.URL.createObjectURL(blob)
document.body.removeChild(link) const link = document.createElement('a')
ElMessage.success('下载已启动') link.href = url
link.download = `${currentResume.value.name}_resume.pdf`
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(url)
ElMessage.success('下载已启动')
} catch (e) {
ElMessage.error('下载失败,请重试')
console.error(e)
}
} }
</script> </script>