|
|
@@ -0,0 +1,250 @@
|
|
|
+<template>
|
|
|
+ <div class="upload-resume">
|
|
|
+ <div class="attached-resume">
|
|
|
+ <div class="attached-resume-title flex justify-between align-center">
|
|
|
+ <div>附件管理</div>
|
|
|
+ <div class="upload-btn" @click="handleUploadClick">上传</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 附件列表 -->
|
|
|
+ <div>
|
|
|
+ <div class="attached-resume-label">
|
|
|
+ 文件({{ fileList.length }}/{{ limit }})
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-for="(file, index) in fileList" :key="index"
|
|
|
+ class="flex align-center justify-between attached-resume-item">
|
|
|
+ <div class="flex align-center">
|
|
|
+ <img class="attached-resume-img" src="../../../public/icon-pdf.png" alt="pdf" />
|
|
|
+ <div class="attached-resume-info">
|
|
|
+ <div>{{ file.attachmentName }}</div>
|
|
|
+ <div class="attached-resume-time">
|
|
|
+ {{ file.attachmentSize }}KB 更新于 {{ file.createTime }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="file-actions flex align-center">
|
|
|
+ <el-link type="primary" :href="file.attachmentAddress" target="_blank">查看</el-link>
|
|
|
+ <el-divider direction="vertical"></el-divider>
|
|
|
+ <el-link type="danger" @click="removeFile(file.resumesAttachmentId)">删除</el-link>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 上传弹窗 -->
|
|
|
+ <el-dialog title="上传附件简历" v-model="uploadDialogVisible" width="500px" destroy-on-close>
|
|
|
+ <div style="padding: 20px;">
|
|
|
+ <el-upload drag :limit="limit - fileList.length" :before-upload="beforeUpload"
|
|
|
+ :http-request="uploadFile" :show-file-list="false" accept=".pdf,.doc,.docx">
|
|
|
+ <i class="el-icon-upload"></i>
|
|
|
+ <div class="el-upload__text">
|
|
|
+ 拖拽文件到此处,或 <em>点击上传</em>
|
|
|
+ </div>
|
|
|
+ <div class="el-upload__tip">支持 PDF、Word 文件,最大 5MB</div>
|
|
|
+ </el-upload>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "UploadResume",
|
|
|
+ props: {
|
|
|
+ modelValue: Array,
|
|
|
+ limit: {
|
|
|
+ type: Number,
|
|
|
+ default: 3
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ uploadDialogVisible: false,
|
|
|
+ fileList: this.modelValue || []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ modelValue(val) {
|
|
|
+ this.fileList = val
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ screenHeight() {
|
|
|
+ return window.innerHeight || document.documentElement.clientHeight
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.loadAttachmentList()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ handleUploadClick() {
|
|
|
+ if(this.fileList.length >= this.limit){
|
|
|
+ ElMessage({
|
|
|
+ message: `最多只能上传${this.limit}个文件`,
|
|
|
+ type: 'warning',
|
|
|
+ duration: 1500,
|
|
|
+ offset: this.screenHeight / 2
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.uploadDialogVisible = true
|
|
|
+ },
|
|
|
+ beforeUpload(file) {
|
|
|
+ const validExtensions = ["pdf", "doc", "docx"]
|
|
|
+ const ext = file.name.split('.').pop().toLowerCase()
|
|
|
+ if (!validExtensions.includes(ext)) {
|
|
|
+ this.$message.error("仅支持PDF/DOC/DOCX格式")
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ const isLt5M = file.size / 1024 / 1024 < 5
|
|
|
+ if (!isLt5M) {
|
|
|
+ this.$message.error("文件大小不能超过 5MB")
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ },
|
|
|
+
|
|
|
+ // 上传逻辑
|
|
|
+ async uploadFile(param) {
|
|
|
+ try {
|
|
|
+ const formData = new FormData()
|
|
|
+ formData.append('file', param.file)
|
|
|
+
|
|
|
+ const uploadRes = await this.$Request.post('/alioss/upload', formData)
|
|
|
+ const content = uploadRes.data
|
|
|
+ if (!content) throw new Error('上传失败')
|
|
|
+
|
|
|
+ const fileSize = (param.file.size / 1024).toFixed(1)
|
|
|
+ const saveRes = await this.$Request.post('/app/resumes/saveAttachment', {
|
|
|
+ attachmentAddress: content,
|
|
|
+ attachmentName: param.file.name,
|
|
|
+ attachmentSize: fileSize
|
|
|
+ }, { type: 'json' })
|
|
|
+
|
|
|
+ if (saveRes.code === 0) {
|
|
|
+ ElMessage({
|
|
|
+ message: '保存成功',
|
|
|
+ type: 'success',
|
|
|
+ duration: 1500,
|
|
|
+ offset: this.screenHeight / 2
|
|
|
+ })
|
|
|
+ // 上传成功后重新获取附件列表
|
|
|
+ this.loadAttachmentList()
|
|
|
+ this.uploadDialogVisible = false
|
|
|
+ } else {
|
|
|
+ param.onError()
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ console.error('上传出错:', err)
|
|
|
+ param.onError(err)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 获取附件简历列表
|
|
|
+ async loadAttachmentList() {
|
|
|
+ try {
|
|
|
+ const res = await this.$Request.get('/app/resumes/getAttachment')
|
|
|
+ if (res.code === 0 && Array.isArray(res.data)) {
|
|
|
+ res.data.forEach(item => {
|
|
|
+ const ext = item.attachmentName.split('.').pop().toLowerCase()
|
|
|
+ item.fileType = ext
|
|
|
+ })
|
|
|
+ this.fileList = res.data;
|
|
|
+ console.log(this.fileList)
|
|
|
+ this.$emit('update:modelValue', this.fileList)
|
|
|
+ this.$emit('change', this.fileList)
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ console.error('获取附件列表失败:', err)
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 删除文件
|
|
|
+ removeFile(id) {
|
|
|
+ console.log(id)
|
|
|
+ ElMessageBox.confirm('确认删除该条内容么?', '提示', {
|
|
|
+ confirmButtonText: '确认',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning'
|
|
|
+ }).then(() => {
|
|
|
+ // 确认删除
|
|
|
+ this.$Request.post('/app/resumes/deleteAttachment',{ resumesAttachmentId: id}, { type: 'json' }).then((res) => {
|
|
|
+ if(res.code == 0){
|
|
|
+ ElMessage({
|
|
|
+ message: '删除成功',
|
|
|
+ type: 'success',
|
|
|
+ duration: 1500,
|
|
|
+ offset: this.screenHeight / 2
|
|
|
+ });
|
|
|
+ this.loadAttachmentList()
|
|
|
+ }
|
|
|
+
|
|
|
+ }).catch(() => {
|
|
|
+ });
|
|
|
+ });
|
|
|
+ // this.fileList.splice(index, 1)
|
|
|
+ // this.$emit("update:modelValue", this.fileList)
|
|
|
+ // this.$emit("change", this.fileList)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.upload-resume {
|
|
|
+ width: 250px;
|
|
|
+}
|
|
|
+.attached-resume {
|
|
|
+ padding: 20px;
|
|
|
+ border-radius: 15px;
|
|
|
+ background-color: #fff;
|
|
|
+ width: 100%;
|
|
|
+
|
|
|
+ // height: 458px;
|
|
|
+ .attached-resume-title {
|
|
|
+ border-bottom: 1px solid #e4e7ed;
|
|
|
+ padding-bottom: 18px;
|
|
|
+ color: #303133;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+
|
|
|
+ .attached-resume-label {
|
|
|
+ padding: 15px 0;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .attached-resume-item {
|
|
|
+ padding-bottom: 20px;
|
|
|
+
|
|
|
+ .attached-resume-img {
|
|
|
+ height: 44px;
|
|
|
+ margin-right: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .attached-resume-info {
|
|
|
+ line-height: 24px;
|
|
|
+ margin-bottom: 4px;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .attached-resume-time {
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 17px;
|
|
|
+ color: #8d92a1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .file-actions{
|
|
|
+ flex-shrink: 0;
|
|
|
+ :deep(.el-link){
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.attached-resume:hover {
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+</style>
|