Переглянути джерело

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

lifanagju_citu 6 місяців тому
батько
коміт
f9858a887e

+ 5 - 0
src/api/common/index.js

@@ -219,6 +219,11 @@ export const uploadFile = async (data) => {
   return await request.upload({ url: '/app-api/menduner/system/file/upload', data })
 }
 
+// 图片上传
+export const uploadImage = async (data) => {
+  return await request.upload({ url: '/app-api/infra/file/upload', data })
+}
+
 // 获取当前登录的企业用户信息
 export const getEnterprisingUserInfo = async (params) => {
   return await request.get({

+ 1 - 1
src/components/Enterprise/components/positions.vue

@@ -271,7 +271,7 @@ const toDetails = async (info) => {
     url += `&enterprise=${info.contact.enterpriseId}`
   }
 
-  router.push(url)
+  window.open(url)
 }
 
 const showLogin = ref(false)

+ 2 - 0
src/components/FormUI/cascade/index.vue

@@ -17,6 +17,8 @@
         style="width: 100%;"
         :props="prop"
         :options="item.items"
+        :collapse-tags="item.collapseTags || false"
+        :collapse-tags-tooltip="true"
         @blur="handleBlur"
         @change="handleChange"
       ></el-cascader>

+ 1 - 1
src/components/Position/longStrip.vue

@@ -124,7 +124,7 @@ const toDetails = async (info) => {
     url += `&enterprise=${info.contact.enterpriseId}`
   }
 
-  router.push(url)
+  window.open(url)
 }
 
 const showLogin = ref(false)

+ 2 - 2
src/components/Upload/img.vue

@@ -21,7 +21,7 @@
 // 图片上传
 defineOptions({ name: 'upload-img'})
 import { ref, watch } from 'vue'
-import { uploadFile } from '@/api/common'
+import { uploadImage } from '@/api/common'
 import { useI18n } from '@/hooks/web/useI18n'
 import Snackbar from '@/plugins/snackbar'
 
@@ -63,7 +63,7 @@ const handleUploadFile = async (e) => {
   }
   const formData = new FormData()
   formData.append('file', file)
-  const { data } = await uploadFile(formData)
+  const { data } = await uploadImage(formData)
   if (!data) return Snackbar.error('上传失败')
   src.value = data
   if (props.showSnackbar) Snackbar.success(t('common.uploadSucMsg'))

+ 1 - 1
src/views/about/index.vue

@@ -3,7 +3,7 @@
     <div v-if="showBanner" class="banner"></div>
     <div class="default-width white-bgc px-10" :class="{'my-3': showBanner}">
       <div class="pb-15 pt-10">
-        <h1 class="title">公司简介</h1>
+        <h1 class="title">{{ showBanner ? '公司简介' : '了解门墩儿' }}</h1>
         <p class="mb-5 mt-10">门墩儿是聚焦酒店及现代服务业人力资源技术与人才数据服务的互联网科技公司。</p>
         <p>通过一体化的人力资源运营技术平台,致力于为企业提供人力资源数据服务支持,同时基于数据与技术,为企业提供线上招聘、猎头、实习生及知识付费等全方位人力资源解决方案。</p>
       </div>

+ 2 - 5
src/views/login/index.vue

@@ -260,8 +260,8 @@ const verifySuccess = (params) => {
   align-items: center;
   justify-content: center;
   width: 100%;
-  // height: 84vh;
-  height: calc(100vh - 50px);
+  height: 78vh;
+  // height: calc(100vh - 50px);
   margin-top: 50px;
 }
 .login-change {
@@ -292,7 +292,6 @@ const verifySuccess = (params) => {
 .login-tips {
   width: 100%;
   font-size: 12px;
-  // text-align: center;
   display: flex;
   justify-content: center;
   align-items: center;
@@ -309,8 +308,6 @@ const verifySuccess = (params) => {
 .aboutBox {
   width: 100%;
   background-color: #fff;
-  // overflow-x: auto;
-  margin-top: -115px;
 }
 .carousel {
   :deep(.v-window) {

+ 25 - 11
src/views/mall/exchange.vue

@@ -35,8 +35,7 @@ import Dialog from '@/components/CtDialog'
 import Snackbar from '@/plugins/snackbar'
 import { redeemSubmit } from '@/api/mall'
 import { useUserStore } from '@/store/user'
-import { checkAddress } from '@/utils/validate'
-
+import { getDict } from '@/hooks/web/useDictionaries'
 
 const emit = defineEmits(['login', 'toTaskCenter'])
 defineProps({
@@ -65,19 +64,25 @@ const formItems = ref({
       outlined: true,
       rules: [v => !!v || '请填写收货人联系电话']
     },
+    {
+      type: 'cascade',
+      key: 'address',
+      value: [],
+      label: '收货地址',
+      itemText: 'name',
+      itemValue: 'name',
+      required: true,
+      clearable: false,
+      emitPath: true,
+      items: []
+    },
     {
       type: 'textarea',
       key: 'contactAddress',
-      value: '先烈中路100号大院203室',
+      value: '',
       hide: false,
-      label: '收获详细地址 *',
-      rules: [
-        v => !!v || '请填写收获详细地址',
-        value => {
-          if (!value || (value && checkAddress(value))) return true
-          return '请输入正确的注册地址'
-        }
-      ]
+      label: '收货详细地址 *',
+      rules: [ v => !!v || '请填写收货详细地址' ]
     }
   ]
 })
@@ -91,6 +96,12 @@ const dataList = ref([
   { name: '减压捏捏乐', point: 500, url: 'https://minio.menduner.com/dev/menduner/pinchMusic.png', type: 1 }
 ])
 
+// 期望城市、其它感兴趣的城市
+getDict('areaTreeData', null, 'areaTreeData').then(({ data }) => {
+  data = data?.length && data || []
+  formItems.value.options.find(e => e.key === 'address').items = data
+})
+
 // 详情说明弹窗
 const showDetail = ref(false)
 const detailItem = ref({})
@@ -117,6 +128,9 @@ const handleSubmit = async () =>{
   formItems.value.options.forEach(e => {
     obj[e.key] = e.value
   })
+  if (!obj.address || !obj.address.length) return Snackbar.warning('请选择收货地址')
+  obj.contactAddress = obj.address.join('') + obj.contactAddress
+  delete obj.address
   await redeemSubmit(obj)
   Snackbar.success('提交成功')
   showDetail.value = false

+ 1 - 1
src/views/recruit/entRegister/register.vue

@@ -42,7 +42,7 @@
                   :value="licenseUrl"
                   :showSnackbar="false" 
                   @imgClick="showPreview = !showPreview" 
-                  :showCursor="true" 
+                  :showCursor="true"
                   @success="handleUploadImg" 
                   @delete="handleDeleteImg"
                 ></Img>

+ 2 - 2
src/views/recruit/enterprise/entInfoSetting/informationSettingsComponents/enterpriseAlbum.vue

@@ -42,7 +42,7 @@
 defineOptions({name: 'informationSettingsComponents-enterpriseAlbum'})
 import { ref } from 'vue'
 import { checkIsImage } from '@/utils'
-import { uploadFile } from '@/api/common'
+import { uploadImage } from '@/api/common'
 import { useI18n } from '@/hooks/web/useI18n'
 import { getEnterpriseBaseInfo, updateEnterpriseAlbum } from '@/api/enterprise'
 import Snackbar from '@/plugins/snackbar'
@@ -111,7 +111,7 @@ const handleUploadFile = async (e) => {
   }
   const formData = new FormData()
   formData.append('file', file)
-  const { data } = await uploadFile(formData)
+  const { data } = await uploadImage(formData)
   if (!data) return
   Snackbar.success(t('common.uploadSucMsg'))
   imgList.value.push(data)

+ 3 - 3
src/views/recruit/enterprise/entInfoSetting/informationSettingsComponents/enterpriseLogo.vue

@@ -45,7 +45,7 @@
 defineOptions({name: 'informationSettingsComponents-enterpriseLogo'})
 import { useUserStore } from '@/store/user'; const userStore = useUserStore()
 import { ref } from 'vue'
-import { uploadFile } from '@/api/common'
+import { uploadImage } from '@/api/common'
 import { useI18n } from '@/hooks/web/useI18n'
 import { updateEnterpriseLogo, getEnterpriseBaseInfo } from '@/api/enterprise'
 import Snackbar from '@/plugins/snackbar'
@@ -90,7 +90,7 @@ const handleHideCopper = (data) => {
 
     const formData = new FormData()
     formData.append('file', file)
-    uploadFile(formData).then(async ({ data }) => {
+    uploadImage(formData).then(async ({ data }) => {
       if (!data) return
       Snackbar.success(t('common.uploadSucMsg'))
       await updateEnterpriseLogo(data)
@@ -128,7 +128,7 @@ const handleUploadFile = async (e) => {
       // 大小符合直接上传logo
       const formData = new FormData()
       formData.append('file', file)
-      const { data } = await uploadFile(formData)
+      const { data } = await uploadImage(formData)
       if (!data) return
       Snackbar.success(t('common.uploadSucMsg'))
       await updateEnterpriseLogo(data)

+ 2 - 2
src/views/recruit/enterprise/staffInfoSetting/index.vue

@@ -30,7 +30,7 @@
 defineOptions({ name: 'information-setting'})
 import { ref } from 'vue'
 import { saveUserInfo } from '@/api/enterprise'
-import { uploadFile } from '@/api/common'
+import { uploadImage } from '@/api/common'
 import { useI18n } from '@/hooks/web/useI18n'
 // import { getDict } from '@/hooks/web/useDictionaries'
 import { useUserStore } from '@/store/user'
@@ -161,7 +161,7 @@ const handleHideCopper = (data) => {
 
     const formData = new FormData()
     formData.append('file', file)
-    uploadFile(formData).then(async ({ data }) => {
+    uploadImage(formData).then(async ({ data }) => {
       if (!data) return
       formItems.value.options.find(e => e.key === 'avatar').value = data
     })

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

@@ -109,7 +109,7 @@ import { checkEmail } from '@/utils/validate'
 import { updateGroupUserAccount } from '@/api/enterprise'
 import { getDict } from '@/hooks/web/useDictionaries'
 import { getUserAvatar } from '@/utils/avatar'
-import { uploadFile } from '@/api/common'
+import { uploadImage } from '@/api/common'
 import { getToken } from '@/utils/auth'
 
 const { t } = useI18n()
@@ -312,7 +312,7 @@ const handleHideCopper = (data) => {
 
     const formData = new FormData()
     formData.append('file', file)
-    uploadFile(formData).then(async ({ data }) => {
+    uploadImage(formData).then(async ({ data }) => {
       if (!data) return
       formItems.value.options.find(e => e.key === 'avatar').value = data
     })

+ 4 - 2
src/views/recruit/personal/PersonalCenter/resume/online/components/basicInfo.vue

@@ -118,7 +118,7 @@ import { getDict } from '@/hooks/web/useDictionaries'
 // import { timesTampChange } from '@/utils/date'
 import { updatePersonAvatar, saveResumeBasicInfo } from '@/api/recruit/personal/resume'
 import { useUserStore } from '@/store/user'
-import { uploadFile } from '@/api/common'
+import { uploadImage } from '@/api/common'
 import { getUserAvatar } from '@/utils/avatar'
 import { useI18n } from '@/hooks/web/useI18n'
 import portrait from './portrait.vue'
@@ -180,7 +180,7 @@ const handleHideCopper = (data) => {
     const formData = new FormData()
     formData.append('file', file)
     overlay.value = true
-    uploadFile(formData).then(async ({data}) => {
+    uploadImage(formData).then(async ({data}) => {
       if (!data) return
       await updatePersonAvatar(data)
       setTimeout(async () => {
@@ -342,6 +342,7 @@ const items = ref({
       itemText: 'name',
       itemValue: 'id',
       required: true,
+      checkStrictly: true,
       clearable: false,
       col: 6,
       items: [],
@@ -354,6 +355,7 @@ const items = ref({
       label: '户籍地',
       itemText: 'name',
       itemValue: 'id',
+      checkStrictly: true,
       required: false,
       clearable: true,
       col: 6,

+ 38 - 134
src/views/recruit/personal/PersonalCenter/resume/online/components/jobIntention.vue

@@ -36,57 +36,7 @@
       <div v-else class="resumeNoDataText">{{ $t('resume.dataDefaultPrompt') }}{{ $t('resume.jobIntention') }}...</div>
     </div>
     <div v-if="isAdd" class="mt-2">
-      <CtForm ref="formPageRef" :items="items" style="width: 100%;">
-        <!-- 期望岗位 -->
-        <!-- <template #positionId="{ item }">
-          <v-menu :close-delay="1" :open-delay="0" v-bind="$attrs">
-            <template v-slot:activator="{  props }">
-              <textUI
-                :modelValue="item.value"
-                :item="item"
-                v-bind="props"
-                style="position: relative;"
-              ></textUI>
-            </template>
-            <jobTypeCard class="jobTypeCardBox" :select="[query.positionId].filter(Boolean)" :isSingle="true" @handleJobClick="handleJobClickItem"></jobTypeCard>
-          </v-menu>
-        </template> -->
-        <!-- 期望行业 -->
-        <template #industryIdList="{ item }">
-          <v-menu :close-delay="1" :open-delay="0" v-bind="$attrs" :close-on-content-click="false">
-            <template v-slot:activator="{  props }">
-              <textUI
-                v-model="item.value"
-                :item="item"
-                v-bind="props"
-              >
-                <template #default>
-                  <v-chip v-for="k in currentSelect" :key="k.id" class="mr-1" closable @click:close="handleIndustryClear(k)">{{ k.nameCn }}</v-chip>
-                </template>
-              </textUI>
-            </template>
-            <industryTypeCard :select="query.industryIdList" :currentData="currentSelect" showSelect @handleClickIndustry="handleIndustry"></industryTypeCard>
-          </v-menu>
-        </template>
-        <!-- 其它感兴趣的城市 -->
-        <template #interestedAreaIdList="{ item }">
-          <v-menu :close-delay="1" :open-delay="0" v-bind="$attrs" :close-on-content-click="false">
-            <template v-slot:activator="{  props }">
-              <TextInput
-                v-model="item.value"
-                :item="item"
-                v-bind="props"
-                style="position: relative;"
-              >
-                <template #default>
-                  <v-chip v-for="k in areaSelect" :key="k.id" class="mr-1" closable @click:close="handleAreaClear(k)">{{ k.name }}</v-chip>
-                </template>
-              </TextInput>
-            </template>
-            <AreaSelect :select="query.interestedAreaIdList" :currentData="areaSelect" :limit="false" showSelect @handleClick="handleArea"></AreaSelect>
-          </v-menu>
-        </template>
-      </CtForm>
+      <CtForm ref="formPageRef" :items="items" style="width: 100%;"></CtForm>
       <div class="text-end">
         <v-btn class="half-button mr-3" variant="tonal" @click="isAdd = false; resetForm()">{{ $t('common.cancel') }}</v-btn>
         <v-btn color="primary" class="half-button" @click="handleSave">{{ $t('common.save') }}</v-btn>
@@ -98,9 +48,6 @@
 <script setup name="jobIntention">
 import { ref, reactive } from 'vue'
 import CtForm from '@/components/CtForm'
-import textUI from '@/components/FormUI/TextInput'
-// import jobTypeCard from '@/components/jobTypeCard'
-import industryTypeCard from '@/components/industryTypeCard'
 import Snackbar from '@/plugins/snackbar'
 import Confirm from '@/plugins/confirm'
 import { saveResumeJobInterested, getResumeJobInterested, deleteResumeJobInterested } from '@/api/recruit/personal/resume'
@@ -129,26 +76,21 @@ const items = ref({
       rules: [v => !!v || '请选择期望岗位'],
       items: [],
     },
-    // {
-    //   slotName: 'positionId',
-    //   key: 'positionId',
-    //   value: '',
-    //   col: 6,
-    //   label: '期望岗位 *',
-    //   flexStyle: 'mr-3',
-    //   valueKey: 'position', 
-    //   hideDetails: true,
-    //   outlined: true,
-    //   rules: [v => !!v || '请选择期望岗位']
-    // },
     {
-      slotName: 'industryIdList',
+      type: 'cascade',
       key: 'industryIdList',
-      value: '',
-      outlined: true,
-      placeholder: '期望行业 *',
+      value: [],
+      default: [],
+      label: '期望行业',
+      itemText: 'nameCn',
+      itemValue: 'id',
+      required: true,
+      collapseTags: true,
+      clearable: false,
+      multiple: true,
       col: 6,
-      // rules: [v => !!v || '请选择期望行业']
+      rules: [v => !!v || '请选择期望行业'],
+      items: [],
     },
     {
       type: 'number',
@@ -220,25 +162,31 @@ const items = ref({
       itemValue: 'id',
       required: true,
       clearable: false,
+      checkStrictly: true,
       col: 6,
       items: [],
     },
     {
-      slotName: 'interestedAreaIdList',
+      type: 'cascade',
       key: 'interestedAreaIdList',
-      value: '',
-      placeholder: '其它感兴趣的城市'
+      value: [],
+      label: '其它感兴趣的城市',
+      itemText: 'name',
+      itemValue: 'id',
+      collapseTags: true,
+      checkStrictly: true,
+      clearable: false,
+      multiple: true,
+      items: []
     }
   ]
 })
 
+// 期望城市、其它感兴趣的城市
 getDict('areaTreeData', null, 'areaTreeData').then(({ data }) => {
   data = data?.length && data || []
-  if (!data?.length) return console.error('areaTreeData获取失败!')
-  const chinaTreeData = data
-  if (!chinaTreeData?.length) return console.error('chinaTreeData获取失败!')
-  const item = items.value.options.find(e => e.key === 'workAreaId')
-  if (item?.items) item.items = chinaTreeData
+  items.value.options.find(e => e.key === 'workAreaId').items = data
+  items.value.options.find(e => e.key === 'interestedAreaIdList').items = data
 })
 
 // 求职类型
@@ -252,6 +200,12 @@ getDict('positionTreeData', null, 'positionTreeData').then(({ data }) => {
   items.value.options.find(e => e.key === 'positionId').items = data
 })
 
+// 期望行业
+getDict('industryTreeData', null, 'industryTreeData').then(({ data }) => {
+  data = data?.length && data || []
+  items.value.options.find(e => e.key === 'industryIdList').items = data
+})
+
 // 获取求职意向
 const interestList = ref([])
 const getJobInterested = async () => {
@@ -266,65 +220,21 @@ const getJobInterested = async () => {
 }
 getJobInterested()
 
-const setValue = (key, value) => {
-  items.value.options.find(e => e.key === key).value = value
-}
-
-// // 期望职位
-// const handleJobClickItem = (list, name) => {
-//   if (!list.length) return
-//   query.positionId = list[0]
-//   setValue('positionId', name)
-// }
-
-// 行业类型
-let currentSelect = reactive([])
-const handleIndustry = (list, arr) => {
-  if (!list.length) return setValue('industryIdList', '')
-  query.industryIdList = list
-  currentSelect = arr
-  // const str = arr.map(e => e.nameCn).join('、')
-  // setValue('industryIdList', str)
-}
-
-const handleIndustryClear = (k) => {
-  query.industryIdList = query.industryIdList.filter(i => i !== k.id)
-  const index = currentSelect.findIndex(i => i.id === k.id)
-  if (index !== -1) currentSelect.splice(index, 1)
-}
-
-// 其它感兴趣的城市
-let areaSelect = reactive([])
-const handleArea = (list, arr) => {
-  if (!list.length) return setValue('interestedAreaIdList', '')
-  query.interestedAreaIdList = list
-  areaSelect = arr
-}
-const handleAreaClear = (k) => {
-  query.interestedAreaIdList = query.interestedAreaIdList.filter(i => Number(i) !== Number(k.id))
-  const index = areaSelect.findIndex(i => Number(i.id) === Number(k.id))
-  if (index !== -1) areaSelect.splice(index, 1)
-}
-
 const resetForm = () => {
   items.value.options.forEach(e => {
-    if (e.key === 'industryIdList') e.value = ''
+    if (e.key === 'industryIdList') e.value = []
     else e.value = null
   })
   editId.value = null
   query = {}
-  currentSelect = []
-  areaSelect = []
 }
 
-const arr = ['payFrom', 'payTo', 'jobType', 'workAreaId', 'positionId']
 const handleSave = async () => {
   const { valid } = await formPageRef.value.formRef.validate()
   if (!valid) return
   items.value.options.forEach(e => {
-    if (arr.includes(e.key)) query[e.key] = e.value 
+    query[e.key] = e.value 
   })
-  if (!query.industryIdList || !query.industryIdList.length) return Snackbar.warning('请选择您的期望行业')
   if (editId.value) query.id = editId.value
   await saveResumeJobInterested(query)
   Snackbar.success('保存成功')
@@ -337,17 +247,11 @@ const handleEdit = async (item) => {
   editId.value = item.id
   items.value.options.forEach(e => {
     query[e.key] = item[e.key] 
-    if (e.valueKey) {
-      e.value = item[e.valueKey]
-    } else e.value = item[e.key]
-    if (e.key === 'industryIdList') e.value = null
+    e.value = item[e.key]
     if (e.key === 'interestedAreaIdList') {
-      e.value = null
-      query.interestedAreaIdList = item.interestedAreaIdList && item.interestedAreaIdList.length ? item.interestedAreaIdList : []
+      e.value = item[e.key] && item[e.key].length ? item[e.key].map(e => Number(e)) : []
     }
   })
-  currentSelect = item.industry
-  areaSelect = item.interestedArea && item.interestedArea.length ? item.interestedArea : []
   isAdd.value = true
 }
 
@@ -384,7 +288,7 @@ const handleDelete = ({ id }) => {
   }
 }
 .text-box {
-  max-width: 200px;
+  max-width: 300px;
   white-space: nowrap;
   text-overflow: ellipsis;
   overflow: hidden;

+ 1 - 1
src/views/recruit/personal/PersonalCenter/resume/online/components/portrait.vue

@@ -2,7 +2,7 @@
   <div>
     <span>个人画像:</span>
     <v-chip size="small" label v-for="(k, i) in list" :key="i" class="mr-2 mb-2" color="primary" closable @click:close="handleDelete(k)">{{ k }}</v-chip>
-    <v-btn icon="mdi-plus" variant="outlined" color="primary" size="small" @click="handleAdd"></v-btn>
+    <v-btn class="ml-3 mb-2" icon="mdi-plus" variant="outlined" color="primary" size="s-small" @click="handleAdd"></v-btn>
   </div>
 
   <div class="d-flex align-center cursor-pointer color-primary mt-3 font-size-18" @click="handleShareCode">

+ 1 - 1
src/views/recruit/personal/PersonalCenter/tradeOrder/index.vue

@@ -53,7 +53,7 @@ const headers = [
   { title: '支付渠道', key: 'payChannelCode', value: item => channelData.value.find(e => e.value === item.payChannelCode)?.label, sortable: false },
   { title: '订单支付时间', key: 'payTime', value: item =>  timesTampChange(item.payTime), sortable: false },
   { title: '退款订单编号', key: 'payReFundId', sortable: false },
-  { title: '退款金额', key: 'refundPrice', sortable: false },
+  { title: '退款金额', key: 'refundPrice', sortable: false, value: item => item.refundPrice && item.refundPrice > 0 ? item.refundPrice / 100 + '元' : '' },
   { title: '退款时间', key: 'refundTime', value: item =>  timesTampChange(item.refundTime), sortable: false },
   { title: '更新时间', key: 'updateTime', value: item =>  timesTampChange(item.updateTime), sortable: false },
 ]

+ 1 - 1
src/views/recruit/personal/position/components/details.vue

@@ -462,7 +462,7 @@ const toDetails = async (info) => {
       url += `&enterprise=${info.contact.enterpriseId}`
     }
 
-    router.push(url)
+    window.open(url)
   } catch (error) {
     console.log(error)
   }