lifanagju_citu 5 mesi fa
parent
commit
3ddc6b801b

+ 10 - 0
src/api/menduner/common/index.ts

@@ -0,0 +1,10 @@
+import request from '@/config/axios'
+
+// 
+export const commonApi = {
+  // 上传文件 // import.meta.env.VITE_UPLOAD_URL
+  uploadFile: async (data: any) => {
+    // return await request.upload({ url: '/menduner/system/file/upload', data })
+    return await request.upload({ url: import.meta.env.VITE_UPLOAD_URL, data })
+  }
+}

+ 77 - 0
src/components/Upload/file.vue

@@ -0,0 +1,77 @@
+<template>
+  <input type="file" ref="fileInput" :accept="accept" style="display: none;" @change="handleUploadFile"/>
+</template>
+
+<script setup>
+defineOptions({ name: 'UploadFile'})
+import { ref } from 'vue'
+import { commonApi } from '@/api/menduner/common'
+// import { commonApi } from '@/api/menduner/common/index'
+
+const message = useMessage() // 消息弹窗
+
+const emits = defineEmits(['success'])
+const props = defineProps({
+  accept: {
+    type: String,
+    default: '.pdf,.doc,.docx'
+  },
+  custom: {
+    type: Boolean,
+    default: false
+  },
+  customName: {
+    type: String,
+    default: ''
+  },
+  path: {
+    type: String,
+    default: 'attachment' // attachment附件, img, video
+  }
+})
+
+const { t } = useI18n() // 国际化
+
+const clicked = ref(false)
+const fileInput = ref()
+
+const trigger = () => {
+  if (clicked.value) return
+  clicked.value = true
+  fileInput.value.click()
+  clicked.value = false
+}
+
+const handleUploadFile = async (e) => {
+  if (!e.target.files.length) return
+  
+  const file = e.target.files[0]
+  const size = file.size
+  if (size / (1024*1024) > 20) {
+    message.warning('文件大小不能超过20M')
+    return
+  }
+  const arr = file.name.split('.')
+
+  // 效验文件格式是否正确
+  const fileType = arr[arr.length - 1]
+  const acceptArr = props.accept.split(',')
+  if (!acceptArr.includes(`.${fileType}`)) return message.warning('请上传指定格式的文件')
+
+  const formData = new FormData()
+  formData.append(props.customName || 'file', file)
+  formData.append('path', props.path)
+  if (props.custom) return emits('success', formData)
+  const { data } = await commonApi.uploadFile(formData)
+  if (!data) return
+  emits('success', data, arr[0], file.name)
+}
+
+defineExpose({
+  trigger
+})
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 106 - 0
src/components/Upload/img.vue

@@ -0,0 +1,106 @@
+<template>
+  <div v-if="!src" class="upload d-flex align-center justify-center flex-column" @click="openFileInput">
+    <v-icon color="#ccc" :size="tips ? 30 : 50">mdi-plus</v-icon>
+    <div class="font-size-12 color-999">{{ tips }}</div>
+    <input
+      type="file"
+      ref="fileInput"
+      accept="image/*"
+      style="display: none;"
+      @change="handleUploadFile"
+    />
+  </div>
+  <div v-else class="" style="position: relative;">
+    <v-icon color="error" class="close" @click="handleClose">mdi-close-circle</v-icon>
+    <v-img :src="src" width="100" height="100" rounded class="imgBox" :class="{'cursor-pointer': showCursor}" @click="emit('imgClick')"></v-img>
+    <div @click="emit('imgClick')" class="color-primary cursor-pointer text-center text-decoration-underline">点击预览</div>
+  </div>
+</template>
+
+<script setup>
+// 图片上传
+defineOptions({ name: 'upload-img'})
+import { ref, watch } from 'vue'
+import { uploadFile } from '@/api/common'
+import { useI18n } from '@/hooks/web/useI18n'
+import Snackbar from '@/plugins/snackbar'
+
+const emit = defineEmits(['success', 'delete', 'imgClick'])
+const props = defineProps({
+  value: String,
+  tips: String,
+  showCursor: Boolean,
+  showSnackbar: {
+    type: Boolean,
+    default: true
+  }
+})
+
+const { t } = useI18n()
+const src = ref('')
+
+watch(() => props.value, (newVal) => {
+  src.value = newVal
+}, { immediate: true }, { deep: true })
+
+// 选择文件
+const fileInput = ref()
+const clicked = ref(false)
+const openFileInput = () => {
+  if (clicked.value) return
+  clicked.value = true
+  fileInput.value.click()
+  clicked.value = false
+}
+
+// 文件上传
+const accept = ['jpg', 'png', 'webp', 'jpeg']
+const handleUploadFile = async (e) => {
+  const file = e.target.files[0]
+  const size = file.size
+  if (size / (1024*1024) > 20) {
+    Snackbar.warning(t('common.fileSizeExceed'))
+    return
+  }
+
+  const fileType = file.name.split('.')[1]
+  if (!accept.includes(fileType)) return Snackbar.warning('请上传图片格式')
+
+  const formData = new FormData()
+  formData.append('file', file)
+  formData.append('path', 'img')
+  const { data } = await uploadFile(formData)
+  if (!data) return Snackbar.error('上传失败')
+  src.value = data
+  if (props.showSnackbar) Snackbar.success(t('common.uploadSucMsg'))
+  emit('success', data)
+}
+
+const handleClose = () => {
+  src.value = ''
+  emit('delete')
+}
+</script>
+
+<style scoped lang="scss">
+.upload {
+  width: 100px;
+  height: 100px;
+  border: 1px solid #ccc;
+  border-radius: 4px;
+  cursor: pointer;
+}
+.imgBox {
+  position: relative;
+  border: 1px solid #ccc;
+  border-radius: 4px;
+  padding: 5px;
+}
+.close {
+  position: absolute;
+  top: -10px;
+  right: -10px;
+  cursor: pointer;
+  z-index: 9;
+}
+</style>

+ 25 - 22
src/views/menduner/system/talentMap/details/components/attachment.vue

@@ -1,18 +1,21 @@
 <template>
   <div>
-    <!-- <el-tabs>
+    <el-tabs>
       <el-tab-pane v-for="item of tableData" :key="item.id" :label="item.title">
-        <vue-office-docx :src="item.url" />
+        <ContentWrap>
+          <IFrame v-if="!loading" :src="item.url" />
+        </ContentWrap>
+        <!-- <vue-office-docx :src="item.url" /> -->
       </el-tab-pane>
-    </el-tabs> -->
-    <el-table v-loading="loading" :data="tableData" :stripe="true">
+    </el-tabs>
+    <!-- <el-table v-loading="loading" :data="tableData" :stripe="true">
       <el-table-column label="附件名称" align="center" prop="title" />
       <el-table-column label="操作" align="center">
         <template #default="scope">
           <el-link type="primary" download :href="scope.row.url" :underline="false" target="_blank">下载</el-link>
         </template>
       </el-table-column>
-    </el-table>
+    </el-table> -->
   </div>
 </template>
 
@@ -25,29 +28,23 @@ const props = defineProps({
 })
 
 const loading = ref(false)
-const tableData = ref([
+const tableData = ref([])
+const tableDataTest = [
   {
     id: "1854433786213732353", 
-    title: "沈和威-13229740092", 
-    url: "https://minio.menduner.com/test/person/1/attachment/7cde29dc69c1403649be55d4c2bfd3d8304c088dc79ab25afe9c4bf55d3b382f.docx", 
+    title: "沈和威-2024-12-02", 
+    url: "https://kkfileview.menduner.com//onlinePreview?url=aHR0cHM6Ly9taW5pby5tZW5kdW5lci5jb20vZGV2LzdjZGUyOWRjNjljMTQwMzY0OWJlNTVkNGMyYmZkM2Q4MzA0YzA4OGRjNzlhYjI1YWZlOWM0YmY1NWQzYjM4MmYuZG9jeA%3D%3D", 
     createTime: 1730966443004, 
     updateTime: 1730966443004
   }, 
-  {
-    id: "1854351450755395585", 
-    title: "沈和威", 
-    url: "https://minio.menduner.com/test/957f8916b9f8e624d9dbe26dd35b31ee44961514e464d413c71419277cbaa38a.pdf", 
-    createTime: 1730946812702, 
-    updateTime: 1730946812702
-  }, 
   {
     id: "1833835593730252802", 
-    title: "沈和威2", 
-    url: "http://menduner.citupro.com:6868/admin-api/infra/file/24/get/7f3b59ce754d452ced40091a63d6db2e08ea8a22a26b7e81f03f133c947aff52.docx", 
+    title: "沈和威-2024-11-15", 
+    url: "https://kkfileview.menduner.com//onlinePreview?url=aHR0cHM6Ly9taW5pby5tZW5kdW5lci5jb20vZGV2LzdmM2I1OWNlNzU0ZDQ1MmNlZDQwMDkxYTYzZDZkYjJlMDhlYThhMjJhMjZiN2U4MWYwM2YxMzNjOTQ3YWZmNTIuZG9jeA%3D%3D", 
     createTime: 1726055451223, 
     updateTime: 1726055451223
   }
-])
+]
 const total = ref(0)
 const queryParams = reactive({
   pageNo: 1,
@@ -58,12 +55,18 @@ const queryParams = reactive({
 const getList = async () => {
   loading.value = true
   try {
-    const data = await PersonInfoApi.getPersonAttachmentList(queryParams)
-    tableData.value = data.list
-    total.value = data.total
+    // const data = await PersonInfoApi.getPersonAttachmentList(queryParams)
+    // tableData.value = data.list
+    // total.value = data.total
+    tableData.value = tableDataTest.map(e => {
+      // if (e.url.startsWith('http://')) {
+      //   e.url = e.url.replace('http://', 'https://');
+      // }
+      return e 
+    })
   } finally {
     loading.value = false
   }
 }
-// getList()
+getList()
 </script>

+ 2 - 2
src/views/menduner/system/talentMap/details/components/info.vue

@@ -1,5 +1,5 @@
 <template>
-  <div>
+  <div v-if="info && Object.keys(info)">
     <!-- <div style="margin-bottom: 12px; text-align: end;">
       <div v-if="isEdit">
         <el-button @click="isEdit = false">取消</el-button>
@@ -90,7 +90,7 @@ const getInfo = async () => {
   const data = await PersonInfoApi.getPersonDetails(props.id)
   info.value = data
 }
-if (props.id) getInfo()
+// if (props.id) getInfo()
 
 // 会员套餐列表
 const packageList = ref([])

+ 45 - 19
src/views/menduner/system/talentMap/index.vue

@@ -18,31 +18,41 @@
         />
       </el-form-item>
       <el-form-item>
-        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button @click="handleQuery"><Icon icon="ep:search" /> 搜索</el-button>
         <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
-        <el-button
+        <!-- <el-button
           type="primary"
           plain
           @click="openForm"
         >
           <Icon icon="ep:plus" class="mr-5px" /> 新增
-        </el-button>
+        </el-button> -->
         <el-button
           type="warning"
           plain
-          @click="handleExport"
-          :loading="exportLoading"
+          @click="handleImportAttachment"
         >
           简历解析
+          <File ref="uploadFile" @success="handleUploadResume"/>
         </el-button>
-        <el-button
+        <!-- <UploadFile
+          v-model="fileUrl"
+          :limit="1"
+          txt="简历解析"
+          :plain="true"
+          :is-show-tip="false"
+          butType="warning"
+          accept=".pdf, .doc"
+          class="ml-10px mt-10px"
+        /> -->
+        <!-- <el-button
           type="success"
           plain
           @click="handleExport"
           :loading="exportLoading"
         >
           <Icon icon="ep:download" class="mr-5px" /> 导出
-        </el-button>
+        </el-button> -->
       </el-form-item>
     </el-form>
     <div>
@@ -93,6 +103,7 @@
 import download from '@/utils/download'
 // import { HuntApi, HuntVO } from '@/api/menduner/system/hunt'
 // import TalentForm from './talentForm.vue'
+import File from '@/components/Upload/file.vue'
 
 /** 猎寻服务 列表 */
 defineOptions({ name: 'TalentMap' })
@@ -166,18 +177,33 @@ const handleDelete = async (id) => {
 }
 
 /** 导出按钮操作 */
-const handleExport = async () => {
-  try {
-    // 导出的二次确认
-    await message.exportConfirm()
-    // 发起导出
-    exportLoading.value = true
-    // const data = await HuntApi.exportHunt(queryParams)
-    // download.excel(data, '猎寻服务.xls')
-  } catch {
-  } finally {
-    exportLoading.value = false
-  }
+// const handleExport = async () => {
+//   try {
+//     // 导出的二次确认
+//     await message.exportConfirm()
+//     // 发起导出
+//     exportLoading.value = true
+//     // const data = await HuntApi.exportHunt(queryParams)
+//     // download.excel(data, '猎寻服务.xls')
+//   } catch {
+//   } finally {
+//     exportLoading.value = false
+//   }
+// }
+
+// 导入附件简历
+const uploadFile = ref()
+const handleImportAttachment = () => {
+  uploadFile.value.trigger()
+}
+
+// 上传附件
+console.log('VITE_UPLOAD_URL:', import.meta.env.VITE_UPLOAD_URL)
+debugger
+const fileUrl = ref('')
+const handleUploadResume = async (url, title, filename) => {
+  debugger
+  fileUrl.value = url
 }
 
 /** 初始化 **/