Преглед изворни кода

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

lifanagju_citu пре 10 месеци
родитељ
комит
e06169541b

+ 3 - 2
src/api/integral.js

@@ -22,8 +22,9 @@ export const getUserRewardPoint = async () => {
 }
 
 // 获取用户积分明细
-export const getUserRewardPointPage = async (pageNo, pageSize) => {
+export const getUserRewardPointPage = async (params) => {
   return await request.get({
-    url: `/app-api/menduner/reward/point/record/page?pageNo=${pageNo}&pageSize=${pageSize}`
+    url: `/app-api/menduner/reward/user/account/record/page`,
+    params
   })
 }

+ 27 - 0
src/components/CtForm/index.vue

@@ -62,6 +62,33 @@
                 :item="item"
                 @change="handleChange(item)"
               ></nestedListGroupUI>
+              <v-file-input
+                v-if="item.type === 'upload'"
+                :prepend-icon="item.prependIcon || ''"
+                :append-icon="item.appendIcon"
+                :append-outer-icon="item.appendOuterIcon"
+                :show-size="item.showSize"
+                variant="outlined"
+                density="compact"
+                v-model="item.value"
+                :placeholder="item.placeholder || item.label"
+                :hint="item.hint"
+                :rules="item.rules"
+                :label="item.label"
+                color="primary"
+                :persistent-hint="item.persistentHint"
+                :loading= "item.loading"
+                :disabled="item.disabled"
+                :multiple="item.multiple"
+                :success="item.success"
+                :error="item.error"
+                :accept="item.accept || '.xlsx, .xls, .csv, .pdf, .txt, .doc'"
+                @change="handleChange(item)"
+              >
+                <template v-if="item.selfAppend" #append>
+                  <slot :name="item.selfAppend" :data="item.value"></slot>
+                </template>
+              </v-file-input>
               <DatePicker v-if="item.type === 'datePicker'" v-model="item.value" :options="item.options" :width="item.width" :class="item.class"></DatePicker>
               
               <template v-if="item.slotName">

+ 3 - 2
src/store/user.js

@@ -5,7 +5,7 @@ import { getUserInfo } from '@/api/personal/user'
 import { getEnterpriseUserAccount, getUserAccount } from '@/api/common'
 import Snackbar from '@/plugins/snackbar'
 import { timesTampChange } from '@/utils/date'
-import { updateEventList } from '@/utils/eventList'
+import { getRewardEventList } from '@/utils/eventList'
 import { getBaseInfoDictOfName } from '@/utils/getText'
 
 
@@ -63,7 +63,7 @@ export const useUserStore = defineStore('user',
           const data = await api({ id: this.accountInfo.userId })
           this.userInfo = data
           localStorage.setItem('userInfo', JSON.stringify(data))
-          updateEventList() // 获取规则配置跟踪列表
+          getRewardEventList() // 获取规则配置跟踪列表
           this.getUserAccountInfo()
         } catch (error) {
           Snackbar.error(error.msg)
@@ -120,6 +120,7 @@ export const useUserStore = defineStore('user',
         localStorage.setItem('currentRole', 'enterprise')
         await this.getEnterpriseInfo()
         await this.getEnterpriseUserAccountInfo()
+        getRewardEventList()
         Snackbar.success('切换成功')
       },
       // 获取当前登录的企业用户信息

+ 4 - 0
src/styles/index.css

@@ -65,6 +65,10 @@
   color: #d5e6e8;
 }
 
+.color-error {
+  color: #fe574a;
+}
+
 .font-size-12 {
   font-size: 12px;
 }

+ 1 - 1
src/styles/index.min.css

@@ -1 +1 @@
-:root{--zIndex-dialog:999;--default-bgc:#f2f4f7;--v-primary-base:#00897B;--v-error-base:#fe574a;--v-primary-lighten1:#26A69A;--v-primary-lighten2:#4DB6AC;--v-primary-lighten3:#80CBC4;--v-primary-lighten4:#B2DFDB;--color-222:#222;--color-333:#333;--color-666:#666;--color-777:#777;--color-999:#999;--color-ccc:#ccc;--color-f3:#f3f3f3;--color-f2f4f742:#f2f4f742;--color-f8:#f8f8f8;--color-f2f4f7:#f2f4f7;--color-d5e6e8:#d5e6e8;--zIndex-breadcrumbs:999}.color-222{color:#222}.color-333{color:#333}.color-666{color:#666}.color-777{color:#777}.color-999{color:#999}.color-ccc{color:#ccc}.color-f3f3f3{color:#f3f3f3}.color-f2f4f742{color:#f2f4f742}.color-f8f8f8{color:#f8f8f8}.color-f2f4f7{color:#f2f4f7}.color-d5e6e8{color:#d5e6e8}.font-size-12{font-size:12px}.font-size-13{font-size:13px}.font-size-14{font-size:14px}.font-size-15{font-size:15px}.font-size-16{font-size:16px}.font-size-17{font-size:17px}.font-size-18{font-size:18px}.font-size-19{font-size:19px}.font-size-20{font-size:20px}.buttons{height:36px;width:224px}.half-button{height:36px;width:88px}.default-width{width:1184px;min-width:1184px;max-width:1184px;margin:0 auto}.defaultLink{color:#008978;cursor:pointer}.default-active{color:var(--v-primary-base) !important}.border-bottom-dashed{border-bottom:1px dashed var(--color-ccc)}.white-bgc{background-color:#fff}.ellipsis{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.septal-line{display:inline-block;width:1px;height:10px;vertical-align:middle;background-color:#e0e0e0;margin:0 10px}.resume-box{border-radius:5px;padding:20px 30px;background-color:#fff}.resume-header{display:flex;justify-content:space-between;align-items:center;height:36px}.resume-title{font-weight:700;font-size:18px;border-left:5px solid #00897B;padding-left:12px;line-height:17px}.resumeNoDataText{color:var(--color-666);font-size:14px}.card-box{width:100%;height:100%}
+:root{--zIndex-dialog:999;--default-bgc:#f2f4f7;--v-primary-base:#00897B;--v-error-base:#fe574a;--v-primary-lighten1:#26A69A;--v-primary-lighten2:#4DB6AC;--v-primary-lighten3:#80CBC4;--v-primary-lighten4:#B2DFDB;--color-222:#222;--color-333:#333;--color-666:#666;--color-777:#777;--color-999:#999;--color-ccc:#ccc;--color-f3:#f3f3f3;--color-f2f4f742:#f2f4f742;--color-f8:#f8f8f8;--color-f2f4f7:#f2f4f7;--color-d5e6e8:#d5e6e8;--zIndex-breadcrumbs:999}.color-222{color:#222}.color-333{color:#333}.color-666{color:#666}.color-777{color:#777}.color-999{color:#999}.color-ccc{color:#ccc}.color-f3f3f3{color:#f3f3f3}.color-f2f4f742{color:#f2f4f742}.color-f8f8f8{color:#f8f8f8}.color-f2f4f7{color:#f2f4f7}.color-d5e6e8{color:#d5e6e8}.color-error{color:#fe574a}.font-size-12{font-size:12px}.font-size-13{font-size:13px}.font-size-14{font-size:14px}.font-size-15{font-size:15px}.font-size-16{font-size:16px}.font-size-17{font-size:17px}.font-size-18{font-size:18px}.font-size-19{font-size:19px}.font-size-20{font-size:20px}.buttons{height:36px;width:224px}.half-button{height:36px;width:88px}.default-width{width:1184px;min-width:1184px;max-width:1184px;margin:0 auto}.defaultLink{color:#008978;cursor:pointer}.default-active{color:var(--v-primary-base) !important}.border-bottom-dashed{border-bottom:1px dashed var(--color-ccc)}.white-bgc{background-color:#fff}.ellipsis{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.septal-line{display:inline-block;width:1px;height:10px;vertical-align:middle;background-color:#e0e0e0;margin:0 10px}.resume-box{border-radius:5px;padding:20px 30px;background-color:#fff}.resume-header{display:flex;justify-content:space-between;align-items:center;height:36px}.resume-title{font-weight:700;font-size:18px;border-left:5px solid #00897B;padding-left:12px;line-height:17px}.resumeNoDataText{color:var(--color-666);font-size:14px}.card-box{width:100%;height:100%}

+ 1 - 0
src/styles/index.scss

@@ -32,6 +32,7 @@
 .color-f8f8f8 { color: #f8f8f8; }
 .color-f2f4f7 { color: #f2f4f7; }
 .color-d5e6e8 { color: #d5e6e8; }
+.color-error { color: #fe574a }
 
 .font-size-12 { font-size: 12px; }
 .font-size-13 { font-size: 13px; }

+ 6 - 3
src/utils/eventList.js

@@ -3,14 +3,17 @@ import { getToken } from '@/utils/auth'
 import { ref } from 'vue'
 import { getRewardEventTrackList } from '@/api/integral'
 
+export const getRewardEventList = async () => {
+  const eventList = await getRewardEventTrackList()
+  localStorage.setItem('eventList', JSON.stringify(eventList) ?? [])
+}
+
 // 规则配置跟踪列表(每10分钟更新一次)
 export const updateEventList = () => {
   const timer = ref(null)
   if (getToken()) {
     timer.value = setInterval(async () => {
-      const eventList = await getRewardEventTrackList()
-      // console.log('eventList->获取规则配置跟踪列表')
-      localStorage.setItem('eventList', JSON.stringify(eventList) ?? [])
+      getRewardEventList()
     }, 600000)
   } else {
     timer.value = null

+ 4 - 4
src/views/entrances/list/index.vue

@@ -38,10 +38,10 @@ const smallTitle = [
   '尽享海量VIP特权',
 ]
 const menuList = ref([
-  { icon: 'mdi-account-group-outline', title: '招聘管理系统', to: '/personal' },
-  { icon: 'mdi-shopping-outline', title: '臻选商城系统', to: '/mall' },
-  { icon: 'mdi-chart-bar-stacked', title: '考勤管理系统', to: '' },
-  { icon: 'mdi-checkbox-marked-outline', title: '审批管理系统', to: '' },
+  { icon: 'mdi-account-group-outline', title: '门墩儿直聘', to: '/personal' },
+  { icon: 'mdi-shopping-outline', title: '臻选商城', to: '/mall' },
+  { icon: 'mdi-chart-bar-stacked', title: '考勤管理', to: '' },
+  { icon: 'mdi-checkbox-marked-outline', title: '审批管理', to: '' },
 ])
  const handleClick = (item) => {
   // router.push(item.to)

+ 3 - 3
src/views/integral/pointsManagement/components/integralTable.vue

@@ -20,9 +20,9 @@ defineProps({
 })
 
 const headers = [
-  { title: '来源', key: 'description' },
-  { title: '积分数', key: 'point' },
-  { title: '总积分数', key: 'totalPoint' },
+  { title: '来源', key: 'description', sortable: false},
+  { title: '积分数', key: 'point', sortable: false },
+  { title: '总积分数', key: 'totalPoint', sortable: false },
   { title: '获得时间', key: 'createTime', value: item =>  timesTampChange(item.createTime), sortable: false }
 ]
 </script>

+ 2 - 2
src/views/integral/pointsManagement/components/signInTable.vue

@@ -22,8 +22,8 @@ defineProps({
 
 const { t } = useI18n()
 const headers = [
-  { title: t('taskCenter.signInDays'), key: 'day' },
-  { title: t('taskCenter.points'), key: 'point' },
+  { title: t('taskCenter.signInDays'), key: 'day', sortable: false },
+  { title: t('taskCenter.points'), key: 'point', sortable: false },
   { title: t('taskCenter.createTime'), key: 'createTime', value: item => timesTampChange(item.createTime), sortable: false }
 ]
 </script>

+ 15 - 12
src/views/integral/pointsManagement/pointsDetails.vue

@@ -3,15 +3,15 @@
   <div class="mt-3">
     <v-tabs v-model="tab" style="border-radius: 5px;" align-tabs="start" color="primary" bg-color="#f7f8fa" @update:model-value="handleChangeTab">
       <v-tab :value="1"> {{ $t('points.whole') }}</v-tab>
-      <v-tab :value="2">{{ $t('sys.signIn') }}</v-tab>
+      <!-- <v-tab :value="2">{{ $t('sys.signIn') }}</v-tab> -->
     </v-tabs>
     <TablePage v-if="tab === 1" :items="dataList"></TablePage>
-    <SignInTable v-if="tab === 2" :items="dataList"></SignInTable>
+    <!-- <SignInTable v-if="tab === 2" :items="dataList"></SignInTable> -->
     <CtPagination
       v-if="total > 0"
       :total="total"
-      :page="pageNo"
-      :limit="pageSize"
+      :page="query.pageNo"
+      :limit="query.pageSize"
       @handleChange="handleChangePage"
     ></CtPagination>
   </div>
@@ -21,35 +21,38 @@
 defineOptions({name: 'personal-pointsManagement-pointsDetails'})
 import { ref } from 'vue'
 import TablePage from './components/integralTable.vue'
-import SignInTable from './components/signInTable.vue'
+// import SignInTable from './components/signInTable.vue'
 import { getUserRewardPointPage } from '@/api/integral'
-import { getRewardSignInRecordPage } from '@/api/sign'
+// import { getRewardSignInRecordPage } from '@/api/sign'
 
 const tab = ref(1)
 
 // 数据
 const total = ref(0)
-const pageNo = ref(1)
-const pageSize = ref(10)
+const query = ref({
+  pageNo: 1,
+  pageSize: 10,
+  type: 0
+})
 const dataList = ref([])
 
 // 积分、签到明细
 const getData = async () => {
-  const api = tab.value === 1 ? getUserRewardPointPage : getRewardSignInRecordPage
-  const res = await api(pageNo.value, pageSize.value)
+  // const res = tab.value === 1 ? await getUserRewardPointPage({ pageNo: pageNo.value, pageSize: pageSize.value, type: 0 }) : await getRewardSignInRecordPage(pageNo.value, pageSize.value)
+  const res = await getUserRewardPointPage(query.value)
   dataList.value = res.list
   total.value = res.total
 }
 getData()
 
 const handleChangePage = (e) => {
-  pageNo.value = e
+  query.value.pageNo = e
   getData()
 }
 
 // 切换
 const handleChangeTab = () => {
-  pageNo.value = 1
+  query.value.pageNo = 1
   getData()
 }
 </script>

+ 10 - 7
src/views/recruit/enterprise/memberCenter/myPoints/pointsDetails.vue

@@ -11,8 +11,8 @@
     <CtPagination
       v-if="total > 0"
       :total="total"
-      :page="pageNo"
-      :limit="pageSize"
+      :page="query.pageNo"
+      :limit="query.pageSize"
       @handleChange="handleChangePage"
     ></CtPagination>
   </div>
@@ -27,26 +27,29 @@ const tab = ref(0)
 
 // 数据
 const total = ref(0)
-const pageNo = ref(1)
-const pageSize = ref(10)
+const query = ref({
+  pageNo: 1,
+  pageSize: 10,
+  type: 0
+})
 const dataList = ref([])
 
 // 积分明细
 const getData = async () => {
-  const res = await getUserRewardPointPage(pageNo.value, pageSize.value)
+  const res = await getUserRewardPointPage(query.value)
   dataList.value = res.list
   total.value = res.total
 }
 getData()
 
 const handleChangePage = (e) => {
-  pageNo.value = e
+  query.value.pageNo = e
   getData()
 }
 
 // 切换
 const handleChangeTab = () => {
-  pageNo.value = 1
+  query.value.pageNo = 1
   // tab
   // getData()
 }

+ 21 - 2
src/views/recruit/enterprise/positionManagement/components/baseInfo.vue

@@ -2,7 +2,7 @@
   <div>
     <CtForm ref="formPageRef" :items="items" style="width: 600px;">
       <template #explain>
-        <span style="color: var(--v-error-base); cursor: pointer;" @click="previewFile('https://minio.citupro.com/dev/menduner/%E5%A3%B0%E6%98%8E%EF%BC%9A%E7%A7%AF%E5%88%86%E4%B8%8E%E8%B5%8F%E9%87%91%E6%9C%8D%E5%8A%A1%281%29.docx')">
+        <span style="color: var(--v-error-base); cursor: pointer;" @click="handleViewRule">
           <v-icon size="25" color="error">mdi-help-circle-outline</v-icon>
           众聘岗位规则说明
         </span>
@@ -21,6 +21,10 @@
         </v-menu>
       </template>
     </CtForm>
+
+    <CtDialog :visible="show" :widthType="1" titleClass="text-h6" title="众聘岗位规则说明" :footer="false" @close="show = false">
+      <RulePage />
+    </CtDialog>
   </div>
 </template>
 
@@ -28,14 +32,16 @@
 defineOptions({ name: 'position-add-baseInfo'})
 import CtForm from '@/components/CtForm'
 import { reactive, ref, defineExpose, watch } from 'vue'
-import { previewFile } from '@/utils'
 import textUI from '@/components/FormUI/TextInput'
 import jobTypeCard from '@/components/jobTypeCard'
+import RulePage from './rule.vue'
 
 const props = defineProps({
   itemData: Object
 })
 
+const show = ref(false)
+
 const getValue = (key) => {
   return items.value.options.find(e => e.key === key)
 }
@@ -74,6 +80,7 @@ const handleChangePublic = (val) => {
       if (hireType.value === e.show) e.hide = false
       return
     }
+    if (e.slotName === 'explain') e.hide = val ? false : true
   })
 }
 
@@ -98,6 +105,8 @@ const items = ref({
     {
       slotName: 'explain',
       noParam: true,
+      value: null,
+      hide: true,
       flexStyle: 'mb-3'
     },
     {
@@ -252,6 +261,11 @@ const handleJobClickItem = (list, name) => {
   positionId.value = name
 }
 
+// 众聘规则查看
+const handleViewRule = () => {
+  show.value = true
+}
+
 const getQuery = async () => {
   const { valid } = await formPageRef.value.formRef.validate()
   if (!valid) return
@@ -260,6 +274,11 @@ const getQuery = async () => {
     if (e.noParam) return
     else obj[e.key] = e.value
   })
+  // 不是众聘岗位的默认给0
+  if (!obj.hire) {
+    obj.hirePoint = 0
+    obj.hirePrice = 0
+  }
   query = Object.assign(query, obj)
   return query
 }

+ 52 - 0
src/views/recruit/enterprise/positionManagement/components/rule.vue

@@ -0,0 +1,52 @@
+<template>
+  <div>
+    <div class="text-center">
+      <h2>声明:积分与赏金服务</h2>
+    </div>
+    <div v-for="(val, i) in rule" :key="i" class="mb-5">
+      <h4 class="indent mb-2">{{ val.title }}</h4>
+      <div class="indent color-666" v-if="!Array.isArray(val.desc)">{{ val.desc }}</div>
+      <div v-else class="indent">
+        <div v-for="(k, j) in val.desc" :key="j" class="mb-3 color-666">{{ k }}</div>
+      </div>
+      <div v-if="val.tip" class="color-error">{{ val.tip }}</div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+defineOptions({ name: 'rulePage'})
+
+const rule = [
+  {
+    title: '一、服务介绍',
+    desc: '门墩儿平台致力于为用户提供便捷的积分兑换和赏金服务。在此服务下,用户有权将其系统内符合条件的岗位,通过平台特有的“分享模式”,分享给满足岗位要求的任何第三方。'
+  },
+  {
+    title: '二、信息授权与责任',
+    desc: '推荐人在此郑重承诺,已授权门墩儿平台处理其提供的被推荐人信息,并且已经确保所分享的该信息已取得被推荐人的明确授权和同意。此外,被推荐人也必须确保,所提供的人员信息和简历均通过合法途径获得,不侵犯任何第三方的合法权益。若因推荐人违反上述规范而产生的任何责任、损失和法律后果,推荐人将承担全部责任。'
+  },
+  {
+    title: '三、赏金与积分奖励',
+    desc: [
+      '1、若被推荐的人员成功入职至推荐岗位,并且符合该岗位定制化设置的赏金活动规则要求,推荐人将获得相应的赏金或积分奖励。积分奖励可直接用于在门墩儿平台上兑换礼品或优惠券。',
+      '2、在门墩儿平台上,众聘岗位所直接显示的赏金金额,是平台在扣除服务费用之前的原始金额。这一设置旨在为用户提供一个清晰、透明的赏金信息展示,让用户能够直接了解到岗位推荐的潜在价值。'
+    ],
+    tip: '(需要注意的是:实际发放至用户账户的赏金,将以系统页面所显示金额的70%形式呈现。这是因为门墩儿平台在为用户提供岗位推荐服务的同时,也需要扣除一定的服务费用,以维持平台的正常运营和提供持续、优质的服务。)'
+  },
+  {
+    title: '四、用户须知',
+    desc: '用户在使用门墩儿平台提供的服务时,应仔细阅读并理解赏金活动规则,该规则可于每个岗位的详情页“活动规则”处查阅。用户应确保自己充分理解并接受相关权益内容,以便更好地享受平台服务。'
+  },
+  {
+    title: '五、结语',
+    desc: '门墩儿平台将竭诚为用户提供优质的积分兑换和赏金服务。我们期待与您携手,共同打造一个公平、透明、高效的招聘与推荐平台。'
+  }
+]
+</script>
+
+<style scoped lang="scss">
+.indent {
+  text-indent: 2em;
+}
+</style>

+ 87 - 0
src/views/recruit/personal/shareJob/components/deliveryForm.vue

@@ -0,0 +1,87 @@
+<template>
+  <div style="width: 100%;">
+    <CtForm ref="formPageRef" :items="items"></CtForm>
+  </div>
+</template>
+
+<script setup>
+defineOptions({ name: 'position-add-job-requirements'})
+import { reactive, ref, defineExpose } from 'vue'
+import { useI18n } from '@/hooks/web/useI18n'
+import { uploadFile } from '@/api/common'
+import Snackbar from '@/plugins/snackbar'
+
+const { t }  = useI18n()
+const formPageRef = ref()
+let query = reactive({})
+
+// 上传简历
+const typeList = ['pdf', 'doc', 'docx']
+const handleUpload = async (e) => {
+  const file = e
+  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
+  items.value.options.find(e => e.key === 'url').data = data
+}
+
+const items = ref({
+  options: [
+    {
+      type: 'text',
+      key: 'name',
+      value: '',
+      clearable: true,
+      label: '姓名 *',
+      rules: [v => !!v || '请填写姓名']
+    },
+    {
+      type: 'text',
+      key: 'phone',
+      value: '',
+      clearable: true,
+      label: '手机号码 *',
+      rules: [v => !!v || '请填写手机号码']
+    },
+    {
+      type: 'upload',
+      key: 'url',
+      value: null,
+      data: '',
+      label: '简历 *',
+      accept: '.doc, .docx, .pdf',
+      placeholder: '请上传简历',
+      rules: [v => !!v || '请上传简历'],
+      change: handleUpload
+    }
+  ]
+})
+
+
+const getQuery = async () => {
+  const { valid } = await formPageRef.value.formRef.validate()
+  if (!valid) return
+  const obj = {}
+  items.value.options.forEach(e => {
+    if (Object.prototype.hasOwnProperty.call(e, 'data')) return obj[e.key] = e.data
+    obj[e.key] = e.value
+  })
+  query = Object.assign(query, obj)
+  return query
+}
+
+defineExpose({
+  getQuery
+})
+</script>

+ 24 - 2
src/views/recruit/personal/shareJob/index.vue

@@ -58,18 +58,25 @@
         <div class="mb-5 text-center" style="height: 80px; line-height: 80px;">
           <!-- <v-btn class="mr-2 radius button-item" color="success" variant="outlined">{{ $t('position.communicate') }}</v-btn> -->
           <v-btn class="mr-2 radius button-item" color="success" variant="outlined" target="_blank" to="/recruit/personal/position">{{ $t('position.moreBtn') }}</v-btn>
-          <v-btn class="radius button-item" color="primary" @click="null">{{ $t('position.submitResume') }}</v-btn>
+          <v-btn class="radius button-item" color="primary" @click="handleDelivery">{{ $t('position.submitResume') }}</v-btn>
         </div>
       </div>
     </v-card>
   </div>
+
+  <CtDialog :visible="showResume" :widthType="2" titleClass="text-h6" title="简历投递" @close="handleClose" @submit="handleSubmit">
+    <DeliveryForm ref="deliveryForm"></DeliveryForm>
+  </CtDialog>
+
 </template>
 
 <script setup>
+defineOptions({name: 'recruit-personal-shareJob-index'})
 import { onMounted, ref } from 'vue';
 import { getPositionDetails } from '@/api/position'
 import { dealDictObjData } from '@/utils/position'
-defineOptions({name: 'recruit-personal-shareJob-index'})
+import DeliveryForm from './components/deliveryForm.vue'
+
 // 组件挂载后添加事件监听器  
 const isMobile = ref(false)
 onMounted(() => {
@@ -100,7 +107,22 @@ const desc = [
   { mdi: 'mdi-school-outline', value: 'eduName' },
   { mdi: 'mdi-clock-time-ten-outline', value: 'expName' }
 ]
+
+// 简历投递
+const deliveryForm = ref()
+const showResume = ref(false)
+const handleDelivery = () => {
+  showResume.value = true
+}
+
+const handleClose = () => {
+  showResume.value = false
+}
+const handleSubmit = async () => {
+  console.log(await deliveryForm.value.getQuery(), 'handleSubmit')
+}
 </script>
+
 <style lang="scss" scoped>
 .f-w-600 { font-weight: 600; }
 .radius { border-radius: 8px; }