浏览代码

Merge branch 'dev' of https://git.citupro.com/zhengnaiwen_citu/menduner into dev

lifanagju_citu 11 月之前
父节点
当前提交
4b07b3aafe

+ 9 - 3
src/api/enterprise.js

@@ -92,6 +92,13 @@ export const joinEliminate = async (ids) => {
   })
 }
 
+// 招聘端-牛人管理-入职
+export const personEntryByEnterprise = async (ids) => {
+  return await request.post({
+    url: `/app-admin-api/menduner/system/person-cv/entry?ids=${ids}`
+  })
+}
+
 // 招聘端-系统管理-用户管理-列表
 export const getEnterpriseUserList = async (params) => {
   return await request.get({
@@ -140,10 +147,9 @@ export const getEnterpriseBusiness = async (params) => {
 }
 
 // 招聘端-企业信息-修改企业logo
-export const updateEnterpriseLogo = async (data) => {
+export const updateEnterpriseLogo = async (url) => {
   return await request.post({
-    url: '/app-admin-api/menduner/system/enterprise/logo/update',
-    data
+    url: `/app-admin-api/menduner/system/enterprise/logo/update?logoUrl=${url}`
   })
 }
 

+ 3 - 15
src/views/enterprise/informationManagement/informationSettings.vue

@@ -41,6 +41,7 @@
 </template>
 
 <script setup>
+defineOptions({ name: 'enterprise-system-management-information-settings'})
 import basicInfo from './informationSettingsComponents/basicInfo.vue'
 import enterpriseLogo from './informationSettingsComponents/enterpriseLogo.vue'
 import enterpriseAlbum from './informationSettingsComponents/enterpriseAlbum.vue'
@@ -48,23 +49,10 @@ import welfareLabel from './informationSettingsComponents/welfareLabel.vue'
 import businessInformation from './informationSettingsComponents/businessInformation.vue'
 // import enterpriseVideo from './informationSettingsComponents/enterpriseVideo.vue'
 // import recruitmentQRCode from './informationSettingsComponents/recruitmentQRCode.vue'
-import { provide, ref, watch } from 'vue'
+import { ref, watch } from 'vue'
 import { useRoute, useRouter } from 'vue-router'
-const route = useRoute(); const router = useRouter()
-defineOptions({ name: 'enterprise-system-management-information-settings'})
-
-const infoData = {
-  name: '苏州工业园区娄葑镇香草叶咖啡店', // 企业名称
-  suoZaiDi: '江苏 苏州 吴中区',
-  diZhi: '苏州工业园区斜塘林泉街598号邻里中心翰林大厦2幢N111室',
-  key1: '120.67439051247,31.349085947054',
-  time: new Date().getTime(),
-  select: '1',
-  net: 'https://www.baidu.com',
-  content: '香草叶总部位于苏州,始创于2010年;主营业务是中西结合简餐,以西式为主,适宜商务宴请、休闲小憩、情侣约会、家庭和朋友聚餐。创始人基于对西餐的热爱和菜品高品质的要求,不断研发和丰富菜品,中西结合式简餐,深受顾客朋友们的喜爱。诚邀志同道合者,热爱餐饮业的有志之士加盟香草叶!',
-}
-provide('infoData', JSON.stringify(infoData))
 
+const route = useRoute(); const router = useRouter()
 // tab
 const tab = ref(1)
 watch(() => route?.query?.tabKey, (newVal) => { if (newVal) tab.value = newVal - 0 })

+ 4 - 2
src/views/enterprise/informationManagement/informationSettingsComponents/basicInfo.vue

@@ -23,7 +23,7 @@
       </template>
     </CtForm>
     <div class="text-center">
-      <v-btn color="primary" class="buttons mt-3 mb-10" @click="handleSave">{{ $t('common.save') }}</v-btn>
+      <v-btn color="primary" class="buttons mt-3 mb-10" @click.stop="handleSave">{{ $t('common.save') }}</v-btn>
     </div>
   </div>
 </template>
@@ -33,9 +33,11 @@ defineOptions({name: 'informationSettingsComponents-basicInfo'})
 import { ref, reactive } from 'vue'
 import { getEnterpriseBaseInfo, updateEnterpriseBaseInfo } from '@/api/enterprise'
 import { getDict } from '@/hooks/web/useDictionaries'
+import { useI18n } from '@/hooks/web/useI18n'
 import industryTypeCard from '@/components/industryTypeCard'
 import Snackbar from '@/plugins/snackbar'
 
+const { t } = useI18n()
 const CtFormRef = ref()
 const query = reactive({})
 const formItems = ref({
@@ -191,7 +193,7 @@ const handleSave = async () => {
     query[e.key] = e.value
   })
   await updateEnterpriseBaseInfo(query)
-  Snackbar.success('编辑成功')
+  Snackbar.success(t('common.saveMsg'))
   getBaseInfo()
 }
 </script>

+ 97 - 13
src/views/enterprise/informationManagement/informationSettingsComponents/enterpriseAlbum.vue

@@ -1,37 +1,121 @@
 <!-- 企业相册 -->
 <template>
-  <div v-if="!imgList?.length" class="mt-10 text-center">
-    <Empty></Empty>
-    <v-btn prepend-icon="mdi mdi-upload" color="warning mt-10" @click="{}">{{ $t('common.uploadPictures') }}</v-btn>
+  <div v-if="!imgList.length" class="text-center">
+    <Empty :elevation="false" message="您还没有企业相册,马上去上传图片吧!"></Empty>
+    <v-btn prepend-icon="mdi mdi-upload" color="primary" @click.stop="openFileInput">
+      {{ $t('common.uploadPictures') }}
+      <input
+        type="file"
+        ref="fileInput"
+        accept="image/png, image/jpg, image/jpeg, video/*"
+        style="display: none;"
+        @change="handleUploadFile"
+      />
+    </v-btn>
   </div>
   <div v-else>
-    <div><v-btn prepend-icon="mdi mdi-upload" color="warning mb-5" @click="{}">{{ $t('common.uploadPictures') }}</v-btn></div>
-    <div class="imgItem" v-for="(item, index) in imgList" :key="index">
-      <v-img width="100%" height="100%" :src="item?.url || defaultUrl"></v-img>
+    <div class="mb-3">
+      <v-btn prepend-icon="mdi mdi-upload" color="primary" @click.stop="openFileInput">
+        {{ $t('common.uploadPictures') }}
+        <input
+          type="file"
+          ref="fileInput"
+          accept="image/png, image/jpg, image/jpeg, video/*"
+          style="display: none;"
+          @change="handleUploadFile"
+        />
+      </v-btn>
+    </div>
+    <div class="imgItem" v-for="(item, index) in imgList" :key="index" @click="handleClick(index)">
+      <v-img v-if="checkIsImage(item)" width="100%" height="100%" :src="item"></v-img>
+      <video v-else class="videos-radius mr-3" :src="item" controls height="172" width="172" preload="preload"></video>
       <div class="operate">
-        <span style="font-size: 14px;">设置为封面</span>
-        <span class="mdi mdi-trash-can-outline"></span>
+        <span></span>
+        <span class="mdi mdi-trash-can-outline" @click="handleDelete(item)"></span>
       </div>
     </div>
   </div>
+  <PreviewImg v-if="showPreview" :current="current" :list="imgList" @close="showPreview = !showPreview"></PreviewImg>
 </template>
 
 <script setup>
-import { ref } from 'vue';
-
 defineOptions({name: 'informationSettingsComponents-enterpriseAlbum'})
-const imgList = ref([{ url: false }, { url: 1}])
-const defaultUrl = 'https://minio.citupro.com/dev/menduner/company-avatar.png'
+import { ref } from 'vue'
+import { checkIsImage } from '@/utils'
+import { uploadFile } from '@/api/common'
+import { useI18n } from '@/hooks/web/useI18n'
+import { getEnterpriseBaseInfo, updateEnterpriseAlbum } from '@/api/enterprise'
+import Snackbar from '@/plugins/snackbar'
+import Confirm from '@/plugins/confirm'
+
+const { t } = useI18n()
+const imgList = ref([])
+
+const getInfo = async () => {
+  const data = await getEnterpriseBaseInfo()
+  if (!data) return
+  imgList.value = data.albumList
+}
+getInfo()
+
+// 预览
+const showPreview = ref(false)
+const current = ref(0)
+const handleClick = (index) => {
+  showPreview.value = !showPreview.value
+  current.value = index
+}
+
+// 删除
+const handleDelete = async (url) => {
+  const index = imgList.value.indexOf(url)
+  if (index === -1) return
+  imgList.value.splice(index, 1)
+  Confirm('系统提示', '是否确认删除?').then(async () => {
+    await updateEnterpriseAlbum({ albumList: imgList.value })
+  })
+}
+
+// 选择文件
+const fileInput = ref()
+const clicked = ref(false)
+const openFileInput = () => {
+  if (clicked.value) return
+  clicked.value = true
+  fileInput.value.click()
+  clicked.value = false
+}
+
+// 上传
+const handleUploadFile = async (e) => {
+  const file = e.target.files[0]
+  const size = file.size
+  if (size / (1024*1024) > 10) {
+    Snackbar.warning(t('common.fileSizeExceed'))
+    return
+  }
+  const formData = new FormData()
+  formData.append('file', file)
+  const { data } = await uploadFile(formData)
+  if (!data) return
+  Snackbar.success(t('common.uploadSucMsg'))
+  imgList.value.push(data)
+  await updateEnterpriseAlbum({ albumList: imgList.value })
+  getInfo()
+}
 </script>
+
 <style lang="scss" scoped>
 .imgItem {
-  width: 172px; height: 172px;
+  width: 172px; 
+  height: 172px;
   border: 1px solid rgba(188, 188, 188, 0.5);
   border-radius: 5px;
   margin-right: 24px;
   margin-bottom: 24px;
   display: inline-block;
   position: relative;
+  cursor: pointer;
   .operate {
     display: none;
   }

+ 67 - 40
src/views/enterprise/informationManagement/informationSettingsComponents/enterpriseLogo.vue

@@ -2,42 +2,29 @@
 <template>
   <div>
     <div class="topTip">温馨提示:上传企业LOGO,可以获得更多的关注,提升招聘效果哦!</div>
-    <div class="logoBox d-flex py-4">
-      <div class="logoItem">
-        <span class="typeTitle">矩形LOGO</span>
-        <div class="d-flex mt-8">
-          <div class="file-item mr-4" style="width: 200px;">
-            <v-img v-if="rectangleImageUrl" width="100%" height="100%" :src="rectangleImageUrl"></v-img>
-            <span class="logo">LOGO</span>
-          </div>
-          <div class="d-flex flex-column justify-space-between">
-            <div>
-              <div class="uploadPrompt">LOGO大小:200*130像素</div>
-              <div class="uploadPrompt">仅支持JPG、JPEG、PNG常见图片类</div>
-              <div class="uploadPrompt">型,且文件小于5M</div>
-            </div>
-            <div>
-              <v-btn prepend-icon="mdi mdi-upload" color="warning mb-1" @click="{}">{{ $t('common.uploadPictures') }}</v-btn>
-            </div>
-          </div>
+    <div class="logoBox d-flex py-4 align-center justify-center">
+      <div class="mt-8">
+        <div class="file-item mr-4" style="width: 130px;">
+          <v-img v-if="squareImageUrl" width="100%" height="100%" :src="squareImageUrl"></v-img>
+          <span v-else class="logo">LOGO</span>
         </div>
-      </div>
-      <div class="logoItem">
-        <span class="typeTitle">正方形LOGO</span>
-        <div class="d-flex mt-8">
-          <div class="file-item mr-4" style="width: 130px;">
-            <v-img v-if="squareImageUrl" width="100%" height="100%" :src="squareImageUrl"></v-img>
-            <span class="logo">LOGO</span>
+        <div class="d-flex flex-column justify-space-between">
+          <div class="my-3">
+            <div class="uploadPrompt">LOGO大小:200*130像素</div>
+            <div class="uploadPrompt">仅支持JPG、JPEG、PNG常见图片类</div>
+            <div class="uploadPrompt">型,且文件小于10M</div>
           </div>
-          <div class="d-flex flex-column justify-space-between">
-            <div>
-              <div class="uploadPrompt">LOGO大小:200*130像素</div>
-              <div class="uploadPrompt">仅支持JPG、JPEG、PNG常见图片类</div>
-              <div class="uploadPrompt">型,且文件小于5M</div>
-            </div>
-            <div>
-              <v-btn prepend-icon="mdi mdi-upload" color="warning mb-1" @click="{}">{{ $t('common.uploadPictures') }}</v-btn>
-            </div>
+          <div>
+            <v-btn prepend-icon="mdi mdi-upload" color="primary" @click.stop="openFileInput">
+              {{ $t('common.uploadPictures') }}
+              <input
+                type="file"
+                ref="fileInput"
+                accept="image/png, image/jpg, image/jpeg"
+                style="display: none;"
+                @change="handleUploadFile"
+              />
+            </v-btn>
           </div>
         </div>
       </div>
@@ -46,14 +33,56 @@
 </template>
 
 <script setup>
-import { ref } from 'vue';
-
 defineOptions({name: 'informationSettingsComponents-enterpriseLogo'})
+import { ref } from 'vue'
+import { uploadFile } from '@/api/common'
+import { useI18n } from '@/hooks/web/useI18n'
+import { updateEnterpriseLogo, getEnterpriseBaseInfo } from '@/api/enterprise'
+import Snackbar from '@/plugins/snackbar'
+
+const { t } = useI18n()
+let squareImageUrl = ref('')
+const getInfo = async () => {
+  const data = await getEnterpriseBaseInfo()
+  if (data && data?.logoUrl) squareImageUrl.value = data.logoUrl
+}
+getInfo()
+
+// 选择文件
+const fileInput = ref()
+const clicked = ref(false)
+const openFileInput = () => {
+  if (clicked.value) return
+  clicked.value = true
+  fileInput.value.click()
+  clicked.value = false
+}
 
 // 上传
-let rectangleImageUrl = ref('') // 矩形
-let squareImageUrl = ref('') // 正方形
+const typeList = ['png', 'jpg', 'jpeg']
+const handleUploadFile = async (e) => {
+  const file = e.target.files[0]
+  const size = file.size
+  if (size / (1024*1024) > 10) {
+    Snackbar.warning(t('common.fileSizeExceed'))
+    return
+  }
+  const arr = file.name.split('.')
+  if (typeList.indexOf(arr[arr.length - 1]) < 0) {
+    Snackbar.warning(t('common.fileFormatIncorrect'))
+    return
+  }
+  const formData = new FormData()
+  formData.append('file', file)
+  const { data } = await uploadFile(formData)
+  if (!data) return
+  Snackbar.success(t('common.uploadSucMsg'))
+  await updateEnterpriseLogo(data)
+  getInfo()
+}
+
 </script>
+
 <style lang="scss" scoped>
 .topTip {
   background-color: #f7f8fa;
@@ -64,7 +93,6 @@ let squareImageUrl = ref('') // 正方形
 }
 .uploadPrompt { font-size: 14px; line-height: 24px; }
 .logoBox {
-  .logoItem { width: 50%; padding-right: 10px; }
   .typeTitle {
     font-weight: bold;
   }
@@ -73,7 +101,6 @@ let squareImageUrl = ref('') // 正方形
   height: 130px;
   border-radius: 5px;
   margin-right: 8px;
-  // margin-top: 24px;
   border: 1px solid rgba(188, 188, 188, 0.5);
   text-align: center;
   .logo {

+ 19 - 10
src/views/enterprise/personnelManagement/components/table.vue

@@ -1,7 +1,8 @@
 <template>
   <div>
-    <div class="text-end" v-if="tab === '0'">
-      <v-btn color="primary" :disabled="selected.length ? false : true" variant="tonal" @click="handleJoinEliminate('all')">不合适</v-btn>
+    <div class="text-end">
+      <v-btn v-if="tab === '0'" color="primary" :disabled="selected.length ? false : true" variant="tonal" @click="handleAction('all', 0)">不合适</v-btn>
+      <v-btn v-if="tab === '1'" color="primary" :disabled="selected.length ? false : true" variant="tonal" @click="handleAction('all', 1)">入职</v-btn>
     </div>
     <v-data-table
       class="mt-3"
@@ -27,17 +28,20 @@
         </div>
       </template>
       <template v-slot:item.exp="{ item }">
-        <span v-if="Object.keys(item?.jobExperience)">{{ item.jobExperience.positionName }} {{ item.jobExperience.enterpriseName }}</span>
+        <span v-if="item?.jobExperience && Object.keys(item?.jobExperience).length">{{ item.jobExperience.positionName }} {{ item.jobExperience.enterpriseName }}</span>
         <span v-else>未填写工作经历</span>
       </template>
       <template v-slot:item.edu="{ item }">
-        <span v-if="Object.keys(item?.eduExperience)">{{ timesTampChange(item.eduExperience.startTime).slice(0, 4) }}-{{ timesTampChange(item.eduExperience.endTime).slice(0, 4) }} {{ item.eduExperience.schoolName }}</span>
-        <span v-else></span>
+        <span v-if="item?.eduExperience && Object.keys(item?.eduExperience).length">{{ timesTampChange(item.eduExperience.startTime).slice(0, 4) }}-{{ timesTampChange(item.eduExperience.endTime).slice(0, 4) }} {{ item.eduExperience.schoolName }}</span>
+        <span v-else>未填写教育经历</span>
       </template>
       <template v-slot:item.actions="{ item }">
         <div v-if="tab === '0'">
           <v-btn color="primary" variant="text" @click="previewFile(item.url)">查看简历</v-btn>
-          <v-btn color="primary" variant="text" @click="handleJoinEliminate('', item)">不合适</v-btn>
+          <v-btn color="primary" variant="text" @click="handleAction('', 0, item)">不合适</v-btn>
+        </div>
+        <div v-if="tab === '1'">
+          <v-btn color="primary" variant="text" @click="handleAction('', 1, item)">入职</v-btn>
         </div>
       </template>
     </v-data-table>
@@ -49,7 +53,7 @@ defineOptions({ name: 'table-page'})
 import { ref, computed } from 'vue'
 import { previewFile } from '@/utils'
 import { timesTampChange } from '@/utils/date'
-import { joinEliminate } from '@/api/enterprise'
+import { joinEliminate, personEntryByEnterprise } from '@/api/enterprise'
 import { useI18n } from '@/hooks/web/useI18n'
 import Snackbar from '@/plugins/snackbar'
 
@@ -84,11 +88,16 @@ const handleToPersonDetail = ({ userId, id }) => {
   window.open(`/enterprise/talentPool/details/${userId}?id=${id}`)
 }
 
-// 不合适
-const handleJoinEliminate = async (type, item) => {
+const apiList = [
+  joinEliminate, // 不合适
+  personEntryByEnterprise // 入职
+]
+
+// 不合适、入职
+const handleAction = async (type, index, item) => {
   const ids = type ? selected.value : [item?.id]
   if (!ids) return
-  await joinEliminate(ids)
+  await apiList[index](ids)
   Snackbar.success(t('common.operationSuccessful'))
   emit('refresh')
 }