Files
offerpai_web/src/components/ResumeExportDialog.vue
T

115 lines
3.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<!-- 导出简历格式选择弹窗 -->
<el-dialog
v-model="visible"
title="导出简历"
width="3.6rem"
:close-on-click-modal="false"
class="resume-export-dialog"
>
<!-- 格式选择 -->
<el-radio-group v-model="exportFormat" class="resume-export-dialog__radio-group">
<el-radio value="pdf">PDF 简历</el-radio>
<el-radio value="word">Word 简历</el-radio>
</el-radio-group>
<template #footer>
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" :loading="exporting" @click="doExport">下载</el-button>
</template>
</el-dialog>
<!-- 隐藏的简历模板用于导出时渲染DOM -->
<div v-if="exportTemplateData" style="position:absolute;left:-9999px;top:0;">
<JobResumeTemplate ref="exportTemplateRef" :resume-data="exportTemplateData" mode="export" />
</div>
</template>
<script setup lang="ts">
import { ref, computed, nextTick } from 'vue'
import JobResumeTemplate from '@/components/JobResumeTemplate.vue'
import type { ResumeTemplateData } from '@/components/JobResumeTemplate.vue'
import { exportResumePdf, exportResumeWord, loadResumeTemplateData } from '@/utils/resumeExport'
import { ElMessage } from 'element-plus'
// ==================== Props & Emits ====================
const props = defineProps<{
/** 控制弹窗显示/隐藏(v-model */
modelValue: boolean
/** 要导出的简历 ID */
resumeId: string
/** 导出文件名(不含扩展名) */
resumeName?: string
}>()
const emit = defineEmits<{
(e: 'update:modelValue', value: boolean): void
}>()
// ==================== 弹窗显隐双向绑定 ====================
/** 弹窗可见状态 */
const visible = computed({
get: () => props.modelValue,
set: (val: boolean) => emit('update:modelValue', val),
})
// ==================== 导出相关状态 ====================
/** 导出格式:pdf 或 word */
const exportFormat = ref<'pdf' | 'word'>('pdf')
/** 导出中状态 */
const exporting = ref(false)
/** 导出用的简历模板数据 */
const exportTemplateData = ref<ResumeTemplateData | null>(null)
/** 导出用的简历模板组件引用 */
const exportTemplateRef = ref<InstanceType<typeof JobResumeTemplate> | null>(null)
// ==================== 导出逻辑 ====================
/** 执行导出下载 */
async function doExport() {
exporting.value = true
try {
// 1. 加载简历完整数据
const data = await loadResumeTemplateData(props.resumeId)
if (!data) {
ElMessage.error('获取简历数据失败')
return
}
// 2. 设置模板数据,等待DOM渲染
exportTemplateData.value = data
await nextTick()
// 3. 获取渲染后的DOM
const element = exportTemplateRef.value?.resumeRef
if (!element) {
ElMessage.error('简历模板渲染失败')
return
}
const fileName = props.resumeName || '简历'
if (exportFormat.value === 'pdf') {
await exportResumePdf(element, fileName)
} else {
exportResumeWord(element, fileName)
}
ElMessage.success('导出成功')
visible.value = false
} catch (err) {
console.error('[导出简历] 失败', err)
ElMessage.error('导出失败,请稍后重试')
} finally {
exporting.value = false
// 清理隐藏模板数据
exportTemplateData.value = null
}
}
</script>