Sfoglia il codice sorgente

企业-批量上传职位

Xiao_123 7 mesi fa
parent
commit
32535ebfa5

+ 15 - 0
src/api/position.js

@@ -185,6 +185,21 @@ export const getJobAdvertisedExport = async (params) => {
   })
 }
 
+// 招聘端-导出批量上传职位模版
+export const jobAdvertisedTemplateDownload = async () => {
+  return await request.download({
+    url: '/app-api/menduner/system/recruit/job-advertised/import-template'
+  })
+}
+
+// 招聘端-批量上传职位
+export const jobAdvertisedUpload = async (data) => {
+  return await request.upload({
+    url: '/app-api/menduner/system/recruit/job-advertised/import',
+    data
+  })
+}
+
 // 招聘端-发布职位详情
 export const getJobDetails = async (params) => {
   return await request.get({

+ 11 - 2
src/components/Upload/file.vue

@@ -10,10 +10,18 @@ import { useI18n } from '@/hooks/web/useI18n'
 import { uploadFile } from '@/api/common'
 
 const emits = defineEmits(['success'])
-defineProps({
+const props = defineProps({
   accept: {
     type: String,
     default: '.pdf, .doc, .docx'
+  },
+  custom: {
+    type: Boolean,
+    default: false
+  },
+  customName: {
+    type: String,
+    default: ''
   }
 })
 
@@ -40,7 +48,8 @@ const handleUploadFile = async (e) => {
   }
   const arr = file.name.split('.')
   const formData = new FormData()
-  formData.append('file', file)
+  formData.append(props.customName || 'file', file)
+  if (props.custom) return emits('success', formData)
   const { data } = await uploadFile(formData)
   if (!data) return
   emits('success', data, arr[0], file.name)

+ 49 - 14
src/views/recruit/enterprise/positionManagement/index.vue

@@ -6,6 +6,11 @@
       </div>
       <div class="text-end">
         <v-btn prepend-icon="mdi-plus" color="primary" @click="handleAdd">{{ $t('position.newPositionsAdded') }}</v-btn>
+        <v-btn :loading="uploadLoading" prepend-icon="mdi-download-box-outline" color="primary" variant="tonal" class="ml-3" @click="handleUpload">
+          批量上传职位
+          <File ref="uploadFile" :custom="true" customName="multipartFile" accept=".xlsx, .xls" @success="handleUploadPosition"></File>
+        </v-btn>
+        <v-btn :loading="templateLoading" prepend-icon="mdi-export-variant" color="primary" variant="tonal" class="ml-3" @click="handleDownloadTemplate">批量上传模版下载</v-btn>
         <v-btn :loading="exportLoading" prepend-icon="mdi-export-variant" color="primary" variant="tonal" class="ml-3" @click="handleExport">职位列表下载</v-btn>
       </div>
       
@@ -37,11 +42,12 @@ import { ref } from 'vue'
 import TextUI from '@/components/FormUI/TextInput'
 import PositionItem from './components/item.vue'
 import { useRouter } from 'vue-router'; const router = useRouter()
-import { getJobAdvertisedList, getJobAdvertisedExport } from '@/api/position'
+import { getJobAdvertisedList, getJobAdvertisedExport, jobAdvertisedTemplateDownload, jobAdvertisedUpload } from '@/api/position'
 import { dealDictArrayData } from '@/utils/position'
 import { useI18n } from '@/hooks/web/useI18n'
 import { useUserStore } from '@/store/user'
 import download from '@/utils/download'
+import Snackbar from '@/plugins/snackbar'
 
 const store = useUserStore()
 
@@ -55,7 +61,10 @@ const query = ref({
   hasExpiredData: false, // true 到期职位
   hire: false // true 众聘岗位
 })
+const templateLoading = ref(false)
+const uploadLoading = ref(false)
 const exportLoading = ref(false)
+const uploadFile = ref()
 
 const tab = ref(1)
 
@@ -80,19 +89,6 @@ const handleAdd = async () => {
   await store.getEnterpriseUserAccountInfo()
 }
 
-const handleExport = async () => {
-  exportLoading.value = true
-  try {
-    const data = await getJobAdvertisedExport(query.value)
-    const label = tabList.find(e => e.value === tab.value)?.label || ''
-    const txt = `职位列表${label? '(' + label + ')' : ''}`
-    download.excel(data, txt)
-  } finally {
-    exportLoading.value = false
-  }
-}
-
-
 const loading = ref(false)
 // 获取职位列表
 const getPositionList = async () => {
@@ -115,6 +111,45 @@ const getPositionList = async () => {
 }
 getPositionList()
 
+// 职位列表导出
+const handleExport = async () => {
+  exportLoading.value = true
+  try {
+    const data = await getJobAdvertisedExport(query.value)
+    const label = tabList.find(e => e.value === tab.value)?.label || ''
+    const txt = `职位列表${label? '(' + label + ')' : ''}`
+    download.excel(data, txt)
+  } finally {
+    exportLoading.value = false
+  }
+}
+
+// 批量上传模版导出
+const handleDownloadTemplate = async () => {
+  templateLoading.value = true
+  try {
+    const data = await jobAdvertisedTemplateDownload()
+    download.excel(data, '批量上传模版下载')
+  } finally {
+    templateLoading.value = false
+  }
+}
+
+// 批量上传
+const handleUpload = () => {
+  uploadFile.value.trigger()
+}
+const handleUploadPosition = async (formData) => {
+  uploadLoading.value = true
+  try {
+    await jobAdvertisedUpload(formData)
+    Snackbar.success('上传成功')
+    getPositionList()
+  } finally {
+    uploadLoading.value = false
+  }
+}
+
 const handleChangeTab = () => {
   query.value.pageNo = 1
   getPositionList()

+ 6 - 0
src/views/recruit/enterprise/staffInfoSetting/index.vue

@@ -95,6 +95,12 @@ const formItems = ref({
       //     return '请输入正确的电子邮箱'
       //   }
       // ]
+    },
+    {
+      type: 'text',
+      key: 'postName',
+      value: '',
+      label: '所属岗位'
     }
   ]
 })

+ 2 - 62
src/views/recruit/enterprise/systemManagement/groupAccount/index.vue

@@ -43,7 +43,6 @@
           @pageHandleChange="handleChangePage"
         >
           <template #actions="{ item }">
-            <!-- <v-btn color="primary" variant="text" @click="handleBinding(item)">{{ $t('enterprise.userManagement.jobBinding') }}</v-btn> -->
             <v-btn v-if="item.status === '1' && item.userType !== '1'" color="primary" variant="text" @click="handleAction('', 0, item)">{{ $t('enterprise.userManagement.enable') }}</v-btn>
             <v-btn v-if="item.status === '0' && item.userType !== '1'" color="primary" variant="text" @click="handleAction('', 1, item)">{{ $t('enterprise.userManagement.disable') }}</v-btn>
             <v-btn color="primary" variant="text" @click="handleChangeEmail(item)">修改员工邮箱</v-btn>
@@ -53,9 +52,6 @@
     </v-row>
   </v-card>
 
-  <CtDialog :visible="show" :widthType="2" titleClass="text-h6" :title="$t('enterprise.userManagement.selectBinding')" @close="handleClose" @submit="handleSubmit">
-    <CtForm ref="formPageRef" :items="formItems"></CtForm>
-  </CtDialog>
   <CtDialog :visible="showEditEmail" :widthType="2" titleClass="text-h6" title="修改员工邮箱" @close="showEditEmail = false" @submit="handleEditEmailSubmit">
     <CtForm ref="editEmailFormRef" class="mt-3" :items="emailFormItems"></CtForm>
   </CtDialog>
@@ -66,14 +62,12 @@ defineOptions({ name: 'group-account'})
 import { ref } from 'vue'
 import { useI18n } from '@/hooks/web/useI18n'
 import { timesTampChange } from '@/utils/date'
-import { getEnterprisePostPage } from '@/api/recruit/enterprise/system/post'
 import { getEnterpriseTree } from '@/api/recruit/enterprise/system/group'
-import { getEnterpriseUserList, systemUserEnable, systemUserDisable, systemUserBindingPost } from '@/api/recruit/enterprise/system/user'
+import { getEnterpriseUserList, systemUserEnable, systemUserDisable } from '@/api/recruit/enterprise/system/user'
 import Confirm from '@/plugins/confirm'
 import Snackbar from '@/plugins/snackbar'
 import { checkEmail } from '@/utils/validate'
 import { entUpdateEmail } from '@/api/enterprise'
-// import { useRouter } from 'vue-router'; const router = useRouter()
 
 const { t } = useI18n()
 const total = ref(0)
@@ -89,7 +83,7 @@ const treeData = ref([])
 const headers = [
   { title: t('login.username'), key: 'name', sortable: false },
   { title: t('enterprise.userManagement.affiliatedEnterprise'), key: 'enterpriseAnotherName', sortable: false },
-  { title: t('enterprise.userManagement.post'), key: 'post.nameCn', sortable: false },
+  { title: t('enterprise.userManagement.post'), key: 'postName', sortable: false },
   { title: t('enterprise.userManagement.phone'), key: 'phone', sortable: false },
   { title: t('enterprise.userManagement.email'), key: 'email', sortable: false },
   { title: t('enterprise.userManagement.accountType'), key: 'userType', value: item => item.userType === '1' ? t('enterprise.userManagement.administrators') : t('enterprise.userManagement.regularUser'), sortable: false },
@@ -104,26 +98,6 @@ const textItem = ref({
   label: '请输入用户名称搜索'
 })
 
-const show = ref(false)
-const formPageRef = ref()
-const bindQuery = ref({})
-const postList = ref([])
-const formItems = ref({
-  options: [
-    {
-      type: 'autocomplete',
-      key: 'postId',
-      value: null,
-      label: '岗位 *',
-      noAttach: false,
-      itemText: 'nameCn',
-      itemValue: 'id',
-      rules: [v => !!v || '请选择要绑定的岗位'],
-      items: []
-    }
-  ]
-})
-
 // 获取用户列表
 const getUserList = async () => {
   loading.value = true
@@ -160,12 +134,6 @@ const handleClick = (e) => {
   getUserList()
 }
 
-const getPostList = async () => {
-  const res = await getEnterprisePostPage({ pageNo: 1, pageSize: 100 })
-  postList.value = res.list
-}
-getPostList()
-
 const apiList = [
   { api: systemUserEnable, desc: t('enterprise.userManagement.enableAccount') }, 
   { api: systemUserDisable, desc: t('enterprise.userManagement.disableAccount') }
@@ -182,39 +150,11 @@ const handleAction = (type, index, item) => {
   })
 }
 
-// 绑定岗位
-// const handleBinding = async (item) => {
-//   if (!postList.value.length) {
-//     Snackbar.warning(t('enterprise.userManagement.postNodataToAdd'))
-//     return
-//   }
-//   bindQuery.value.id = item.id
-//   const obj = formItems.value.options.find(e => e.key === 'postId')
-//   obj.items = postList.value
-//   obj.value = item.postId
-//   show.value = true
-// }
-
 const handleAdd = (type) => {
   // type: 类型(0 邀请同事 | 1 邀请子公司)
   window.open(`/recruit/enterprise/systemManagement/groupAccount/invite/${type}`)
 }
 
-const handleClose = () => {
-  show.value = false
-  query.value = {}
-}
-
-const handleSubmit = async () => {
-  const { valid } = await formPageRef.value.formRef.validate()
-  if (!valid) return
-  const postId = formItems.value.options.find(e => e.key === 'postId').value
-  await systemUserBindingPost(bindQuery.value.id, postId)
-  Snackbar.success(t('common.operationSuccessful'))
-  handleClose()
-  getUserList()
-}
-
 const emailFormItems = ref({
   options: [
     {