Merge branch 'master' of http://120.26.58.240:8888/r/flexJobMiniApp
| | |
| | | "miniprogram": { |
| | | "list": [ |
| | | { |
| | | "name": "灵工详情", |
| | | "pathName": "subpackages/flexJob/flexJobDetail/flexJobDetail", |
| | | "query": "enterpriseEmployeeId=700a3a67-5da5-49d2-a65a-08ddd661238b", |
| | | "launchMode": "default", |
| | | "scene": null |
| | | }, |
| | | { |
| | | "name": "灵工管理", |
| | | "pathName": "subpackages/flexJobManage/flexJobManage/flexJobManage", |
| | | "query": "", |
| | |
| | | "name": "验收管理", |
| | | "pathName": "subpackages/task/taskCheck/taskCheck", |
| | | "query": "", |
| | | "launchMode": "default", |
| | | "scene": null |
| | | }, |
| | | { |
| | | "name": "灵工详情", |
| | | "pathName": "subpackages/flexJob/flexJobDetail/flexJobDetail", |
| | | "query": "id=c4cfe028-23e7-0be8-ee56-3a11e3743b9d", |
| | | "launchMode": "default", |
| | | "scene": null |
| | | }, |
| | |
| | | <template> |
| | | <ContentView style="background-color: transparent" class="job-detail-content"> |
| | | <FlexJobTopView size="small" class="job-detail-content-top" /> |
| | | <FlexJobTopView |
| | | :avatar="avatar" |
| | | :name="name" |
| | | :age="age" |
| | | :isReal="isReal" |
| | | :gender="gender" |
| | | :personalIdentityContent="personalIdentityContent" |
| | | :educationalBackgroundContent="educationalBackgroundContent" |
| | | :taskCount="taskCount" |
| | | size="small" |
| | | class="job-detail-content-top" |
| | | /> |
| | | <div class="job-detail-content-contact-info"> |
| | | <div class="job-detail-content-contact-info-item"> |
| | | <div class="job-detail-content-contact-info-item-label">手机号:</div> |
| | | <div class="job-detail-content-contact-info-item-text"> |
| | | {{ isCollapse ? '13333333333' : '立即联系后可查看' }} |
| | | {{ isCollapse ? contactPhoneNumber : '立即联系后可查看' }} |
| | | </div> |
| | | </div> |
| | | <div class="job-detail-content-contact-info-item"> |
| | | <div class="job-detail-content-contact-info-item-label">身份证号:</div> |
| | | <div class="job-detail-content-contact-info-item-text"> |
| | | {{ isCollapse ? hiddenIDNumberForEnd6('330902199909123456') : '立即联系后可查看' }} |
| | | {{ isCollapse ? hiddenIDNumberForEnd6(identity) : '立即联系后可查看' }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | fullHeight |
| | | > |
| | | <ProTabPane :title="`简历`" pane-key="1"> |
| | | <curriculumView /> |
| | | <curriculumView |
| | | :userExpectJobs="userExpectJobs" |
| | | :freeTime="freeTime" |
| | | :jobSeekingStatus="jobSeekingStatus" |
| | | :userCredentials="userCredentials" |
| | | :workSeniority="workSeniority" |
| | | :workExperience="workExperience" |
| | | :photos="photos" |
| | | :height="height" |
| | | :weight="weight" |
| | | /> |
| | | </ProTabPane> |
| | | <ProTabPane :title="`经历`" pane-key="2"> |
| | | <experienceView /> |
| | |
| | | import { hiddenIDNumberForEnd6 } from '@12333/utils'; |
| | | import curriculumView from './components/curriculumView.vue'; |
| | | import experienceView from './components/experienceView.vue'; |
| | | import { EnumUserGender } from '@12333/constants'; |
| | | |
| | | defineOptions({ |
| | | name: 'JobDetailContent', |
| | |
| | | |
| | | type Props = { |
| | | isCollapse: boolean; |
| | | |
| | | avatar?: string; |
| | | name?: string; |
| | | gender?: EnumUserGender; |
| | | age?: number; |
| | | isReal?: boolean; |
| | | personalIdentityContent?: string; |
| | | educationalBackgroundContent?: string; |
| | | taskCount?: number; |
| | | contactPhoneNumber?: string; |
| | | identity?: string; |
| | | userId?: string; |
| | | |
| | | userExpectJobs?: API.GetUserResumeQueryResultExpectJob[]; |
| | | freeTime?: API.EnumPersonalFreeTime; |
| | | jobSeekingStatus?: API.EnumPersonalJobSeekingStatus; |
| | | userCredentials?: API.GetUserResumeQueryResultCredential[]; |
| | | workSeniority?: string; |
| | | workExperience?: string; |
| | | photos?: string[]; |
| | | /** 身高 */ |
| | | height?: number; |
| | | /** 体重 */ |
| | | weight?: number; |
| | | |
| | | taskInfoUsers?: API.GetUserResumeQueryResultExperience[]; |
| | | }; |
| | | |
| | | const tab = ref('1'); |
| | |
| | | <div class="curriculum-list"> |
| | | <CurriculumViewItem label="期望岗位:"> |
| | | <div class="curriculum-position-list"> |
| | | <div class="curriculum-position-list-item">客房服务员</div> |
| | | <div class="curriculum-position-list-item">客房服务员</div> |
| | | <div class="curriculum-position-list-item">客房服务员</div> |
| | | <div class="curriculum-position-list-item">客房服务员</div> |
| | | <div class="curriculum-position-list-item">客房员</div> |
| | | <div class="curriculum-position-list-item">客房服务员</div> |
| | | <div class="curriculum-position-list-item">客房服务员</div> |
| | | <div class="curriculum-position-list-item">客房服务员</div> |
| | | <div |
| | | v-for="userExpectJob in userExpectJobs" |
| | | :key="userExpectJob.expectJobCode" |
| | | class="curriculum-position-list-item" |
| | | > |
| | | {{ userExpectJob.expectJobContent }} |
| | | </div> |
| | | </div> |
| | | </CurriculumViewItem> |
| | | <CurriculumViewItem label="空闲时间:" text="不限"> </CurriculumViewItem> |
| | | <CurriculumViewItem label="求职状态:" text="积极找工作"> </CurriculumViewItem> |
| | | <CurriculumViewItem label="空闲时间:" :text="EnumPersonalFreeTimeText[freeTime]"> |
| | | </CurriculumViewItem> |
| | | <CurriculumViewItem |
| | | label="求职状态:" |
| | | :text="EnumPersonalJobSeekingStatusText[jobSeekingStatus]" |
| | | > |
| | | </CurriculumViewItem> |
| | | </div> |
| | | </CellChunk> |
| | | <CellChunk title="资格证书"> |
| | |
| | | :column-num="3" |
| | | :border="false" |
| | | :gutter="20" |
| | | v-if="list.length > 0" |
| | | v-if="_userCredentials.length > 0" |
| | | class="pro-img-grid" |
| | | > |
| | | <nut-grid-item v-for="(item, index) in list" :key="item" class="pro-img-grid-item"> |
| | | <nut-grid-item |
| | | v-for="(item, index) in _userCredentials" |
| | | :key="item" |
| | | class="pro-img-grid-item" |
| | | > |
| | | <div class="pro-img-grid-img-item"> |
| | | <PreviewImage :src="item" class="pro-img-grid-img" :urls="list" /> |
| | | <PreviewImage :src="item" class="pro-img-grid-img" :urls="_userCredentials" /> |
| | | </div> |
| | | </nut-grid-item> |
| | | </nut-grid> |
| | | </CellChunk> |
| | | <CellChunk title="工作经验"> |
| | | <CurriculumViewItem label="工作年限:" text="无工作经验,用户自己填写"> |
| | | <CurriculumViewItem label="工作年限:" :text="workSeniority ? `${workSeniority}年` : ''"> |
| | | </CurriculumViewItem> |
| | | <CurriculumViewItem label="工作经验:" text="客房服务员,用户自己填写"> |
| | | </CurriculumViewItem> |
| | | <CurriculumViewItem label="工作经验:" :text="workExperience"> </CurriculumViewItem> |
| | | </CellChunk> |
| | | <CellChunk title="详细信息"> |
| | | <CurriculumViewItem |
| | | label="身高:" |
| | | text="175 cm" |
| | | :text="`${height} cm`" |
| | | :label-width="labelWidth" |
| | | ></CurriculumViewItem> |
| | | <CurriculumViewItem |
| | | label="体重:" |
| | | text="80 kg" |
| | | :text="`${weight} kg`" |
| | | :label-width="labelWidth" |
| | | ></CurriculumViewItem> |
| | | <CurriculumViewItem label="个人照片:"> |
| | |
| | | :column-num="2" |
| | | :border="false" |
| | | :gutter="20" |
| | | v-if="list.length > 0" |
| | | v-if="_photos.length > 0" |
| | | class="pro-img-grid" |
| | | > |
| | | <nut-grid-item v-for="(item, index) in list" :key="item" class="pro-img-grid-item"> |
| | | <nut-grid-item v-for="(item, index) in _photos" :key="item" class="pro-img-grid-item"> |
| | | <div class="pro-img-grid-img-item"> |
| | | <PreviewImage :src="item" class="pro-img-grid-img" :urls="list" /> |
| | | <PreviewImage :src="item" class="pro-img-grid-img" :urls="_photos" /> |
| | | </div> |
| | | </nut-grid-item> |
| | | </nut-grid> |
| | |
| | | import CurriculumViewItem from './CurriculumViewItem.vue'; |
| | | import { PreviewImage } from '@12333/components'; |
| | | import Taro from '@tarojs/taro'; |
| | | import { EnumPersonalFreeTimeText, EnumPersonalJobSeekingStatusText } from '@12333/constants'; |
| | | import { setOSSLink } from '@12333/utils'; |
| | | |
| | | defineOptions({ |
| | | name: 'curriculumView', |
| | | }); |
| | | |
| | | const labelWidth = Taro.pxTransform(120); |
| | | type Props = { |
| | | userExpectJobs?: API.GetUserResumeQueryResultExpectJob[]; |
| | | freeTime?: API.EnumPersonalFreeTime; |
| | | jobSeekingStatus?: API.EnumPersonalJobSeekingStatus; |
| | | userCredentials?: API.GetUserResumeQueryResultCredential[]; |
| | | workSeniority?: string; |
| | | workExperience?: string; |
| | | photos?: string[]; |
| | | /** 身高 */ |
| | | height?: number; |
| | | /** 体重 */ |
| | | weight?: number; |
| | | }; |
| | | |
| | | const list = ref([ |
| | | 'https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg', |
| | | 'https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg', |
| | | 'https://storage.360buyimg.com/jdc-article/welcomenutui.jpg', |
| | | 'https://storage.360buyimg.com/jdc-article/fristfabu.jpg', |
| | | ]); |
| | | const props = withDefaults(defineProps<Props>(), { |
| | | userExpectJobs: () => [], |
| | | userCredentials: () => [], |
| | | photos: () => [], |
| | | }); |
| | | |
| | | const _userCredentials = computed(() => props.userCredentials.map((x) => setOSSLink(x.img))); |
| | | const _photos = computed(() => props.photos.map((x) => setOSSLink(x))); |
| | | |
| | | const labelWidth = Taro.pxTransform(120); |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | |
| | | <template> |
| | | <ContentScrollView> |
| | | <Cell title="岗位经历"> |
| | | <nut-steps direction="vertical" progress-dot :current="3" class="job-detail-content-steps"> |
| | | <nut-step title="2024.12.24" content="您的订单已经打包完成,商品已发出"></nut-step> |
| | | <nut-step title="2024.12.24" content="您的订单正在配送途中"></nut-step> |
| | | <nut-step title="2024.12.24"> |
| | | <nut-steps |
| | | v-if="taskInfoUsers.length > 0" |
| | | direction="vertical" |
| | | progress-dot |
| | | :current="3" |
| | | class="job-detail-content-steps" |
| | | > |
| | | <nut-step |
| | | v-for="(taskInfoUser, index) in taskInfoUsers" |
| | | :key="index" |
| | | :title="taskInfoUser.signContractTime" |
| | | > |
| | | <template #content> |
| | | <p>收货地址为:</p> |
| | | <p>北京市经济技术开发区科创十一街18号院京东大厦</p> |
| | | <p>在{{ taskInfoUser.enterpriseName }}:</p> |
| | | <p>做过{{ taskInfoUser.name }}</p> |
| | | </template> |
| | | </nut-step> |
| | | </nut-steps> |
| | | <NoData v-else /> |
| | | </Cell> |
| | | </ContentScrollView> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import NoData from '../../NoData/NoData.vue'; |
| | | |
| | | defineOptions({ |
| | | name: 'experienceView', |
| | | }); |
| | | |
| | | type Props = { |
| | | taskInfoUsers?: API.GetUserResumeQueryResultExperience[]; |
| | | }; |
| | | |
| | | const props = withDefaults(defineProps<Props>(), { |
| | | taskInfoUsers: () => [], |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | |
| | | ></ProRadio> |
| | | </QueryMenuItem> |
| | | <QueryMenuItem title="身份"> |
| | | <ProRadio v-model="query.identity" :value-enum="identityList" show-all-btn></ProRadio> |
| | | <ProRadio |
| | | v-model="query.personalIdentityCode" |
| | | :value-enum="identityList" |
| | | show-all-btn |
| | | ></ProRadio> |
| | | </QueryMenuItem> |
| | | <QueryMenuItem> |
| | | <template #title> |
| | |
| | | const query = defineModel<{ |
| | | genderLimit: number | string; |
| | | age: number[]; |
| | | identity: string; |
| | | personalIdentityCode: string; |
| | | certificateType: string; |
| | | }>('query'); |
| | | |
| | |
| | | <template> |
| | | <QueryMenuView @close="handleReset" @confirm="emit('close')" cancelText="重置"> |
| | | <div class="home-query-position-menu-view"> |
| | | <PositionSelectView v-model="query.position" /> |
| | | <PositionSelectView v-model="query.userExpectJobs" /> |
| | | </div> |
| | | </QueryMenuView> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { QueryMenuView, QueryMenuItem, PositionSelectView } from '@12333/components'; |
| | | import { GenderText } from '@12333/constants'; |
| | | |
| | | defineOptions({ |
| | | name: 'HomeQueryPositionMenuView', |
| | |
| | | }>(); |
| | | |
| | | const query = defineModel<{ |
| | | position: string[]; |
| | | userExpectJobs: string[]; |
| | | }>('query'); |
| | | |
| | | const DefaultQuery = { |
| | | ...query.value, |
| | | userExpectJobs: [...query.value.userExpectJobs], |
| | | }; |
| | | |
| | | function handleReset() { |
| | |
| | | title-gutter="8" |
| | | title-scroll |
| | | > |
| | | <ProTabPane :title="`推荐`" :pane-key="HomeOrderType.Recommend"></ProTabPane> |
| | | <ProTabPane :title="`最新`" :pane-key="HomeOrderType.LastShelfTime"></ProTabPane> |
| | | <template #right> |
| | | <Menu> |
| | |
| | | :key="queryState.orderType" |
| | | > |
| | | <template #renderItem="{ item }"> |
| | | <FlexJobCard @click="goFlexJobDetail(item)" :showFooterLeft="false" /> |
| | | <FlexJobCard |
| | | :name="item.name" |
| | | :gender="item.gender" |
| | | :age="item.age" |
| | | :isReal="item.isReal" |
| | | :personalIdentityContent="item.personalIdentityContent" |
| | | :educationalBackgroundContent="item.educationalBackgroundContent" |
| | | :taskCount="item.taskCount" |
| | | :avatar="item.avatar" |
| | | :workExperience="item.workExperience" |
| | | :workSeniority="item.workSeniority" |
| | | @click="goFlexJobDetail(item)" |
| | | :showFooterLeft="false" |
| | | /> |
| | | </template> |
| | | </InfiniteLoading> |
| | | </PageLayoutWithBg> |
| | |
| | | EnumTaskReleaseStatus, |
| | | EnumUserGender, |
| | | } from '@12333/constants'; |
| | | import * as taskServices from '@12333/services/apiV2/task'; |
| | | import _ from 'lodash'; |
| | | import HomeQueryMenuView from './HomeQueryMenuView.vue'; |
| | | import HomeQueryPositionMenuView from './HomeQueryPositionMenuView.vue'; |
| | | import IconLocaltion from '@/assets/home/icon-localtion.png'; |
| | | import { setLocationCity } from '@/utils'; |
| | | import * as userResumeServices from '@12333/services/apiV2/userResume'; |
| | | |
| | | const { locationCity } = useUser(); |
| | | |
| | |
| | | const queryMenuState = reactive({ |
| | | genderLimit: '' as any as EnumUserGender, |
| | | age: [15, 65], |
| | | identity: '', |
| | | personalIdentityCode: '', |
| | | certificateType: '', |
| | | }); |
| | | |
| | | const queryPositionState = reactive({ |
| | | position: [] as string[], |
| | | userExpectJobs: [] as string[], |
| | | }); |
| | | |
| | | const queryState = reactive({ |
| | |
| | | |
| | | const { infiniteLoadingProps } = useInfiniteLoading( |
| | | ({ pageParam }) => { |
| | | let params: API.GetTaskInfosQuery = { |
| | | let params: API.GetUserResumesQuery = { |
| | | pageModel: { |
| | | rows: 20, |
| | | page: pageParam, |
| | | orderInput: [ |
| | | queryState.orderType === HomeOrderType.Recommend |
| | | ? { property: 'recommendStatus', order: EnumPagedListOrder.Desc } |
| | | : { property: 'createdTime', order: EnumPagedListOrder.Desc }, |
| | | ], |
| | | orderInput: [{ property: 'createdTime', order: EnumPagedListOrder.Desc }], |
| | | }, |
| | | // keywords: 'string', |
| | | // time: '2025-08-08T02:58:58.756Z', |
| | | // cityCode: 'string', |
| | | // settlementCycle: 10, |
| | | // benefitCodes: ['string'], |
| | | genderLimit: queryMenuState.genderLimit, |
| | | // status: 10, |
| | | releaseStatus: EnumTaskReleaseStatus.InProcess, |
| | | userExpectJobs: queryPositionState.userExpectJobs, |
| | | gender: queryMenuState.genderLimit, |
| | | personalIdentityCode: queryMenuState.personalIdentityCode, |
| | | // ageMin: queryMenuState.age[0], |
| | | // ageMax: queryMenuState.age[1], |
| | | userCredentials: queryMenuState.certificateType ? [queryMenuState.certificateType] : null, |
| | | }; |
| | | |
| | | return taskServices.getTaskInfos(params, { |
| | | return userResumeServices.getUserResumes(params, { |
| | | showLoading: false, |
| | | }); |
| | | }, |
| | | { |
| | | queryKey: ['taskServices/getTaskInfos', queryState, queryMenuState, queryPositionState], |
| | | queryKey: ['userResumeServices/getUserResumes', queryState, queryMenuState, queryPositionState], |
| | | } |
| | | ); |
| | | |
| | |
| | | selectPositionItem.value?.toggle?.(); |
| | | } |
| | | |
| | | function goFlexJobDetail(item: API.GetTaskInfosQueryResultItem) { |
| | | function goFlexJobDetail(item: API.GetUserResumesQueryResultItem) { |
| | | Taro.navigateTo({ |
| | | url: `${RouterPath.flexJobDetail}?id=${item.id}`, |
| | | url: `${RouterPath.flexJobDetail}?enterpriseEmployeeId=${item.id}`, |
| | | }); |
| | | } |
| | | |
| | |
| | | <template> |
| | | <PageLayoutWithBg class="flexJobDetail-page-wrapper" title="灵工详情" :need-auth="false"> |
| | | <LoadingLayout :loading="isLoading" :error="isError" :loadError="refetch"> |
| | | <JobDetailContent :isCollapse="isCollapse"> |
| | | <JobDetailContent |
| | | :avatar="userResumeInfo.avatar" |
| | | :name="userResumeInfo.name" |
| | | :age="userResumeInfo.age" |
| | | :isReal="userResumeInfo.isReal" |
| | | :gender="userResumeInfo.gender" |
| | | :personalIdentityContent="userResumeInfo.personalIdentityContent" |
| | | :educationalBackgroundContent="userResumeInfo.educationalBackgroundContent" |
| | | :taskCount="userResumeInfo.taskCount" |
| | | :contactPhoneNumber="userResumeInfo.contactPhoneNumber" |
| | | :identity="userResumeInfo.identity" |
| | | :isCollapse="isCollapse" |
| | | :userId="enterpriseEmployeeId" |
| | | :userExpectJobs="userResumeInfo.userExpectJobs" |
| | | :freeTime="userResumeInfo.freeTime" |
| | | :jobSeekingStatus="userResumeInfo.jobSeekingStatus" |
| | | :userCredentials="userResumeInfo.userCredentials" |
| | | :workSeniority="userResumeInfo.workSeniority" |
| | | :workExperience="userResumeInfo.workExperience" |
| | | :photos="userResumeInfo.photos" |
| | | :height="userResumeInfo.height" |
| | | :weight="userResumeInfo.weight" |
| | | :taskInfoUsers="userResumeInfo.taskInfoUsers" |
| | | > |
| | | <template #footer> |
| | | <PageFooterAction |
| | | :icon="IconShare" |
| | |
| | | openType="share" |
| | | ></PageFooterAction> |
| | | <PageFooterAction |
| | | :icon="IconAttentionActive" |
| | | :icon="userResumeInfo.isCollected ? IconAttentionActive : IconAttention" |
| | | text="收藏" |
| | | :isFlex="false" |
| | | @click="handleAttention" |
| | | ></PageFooterAction> |
| | | <PageFooterBtn type="primary" @click="toggle">立即联系</PageFooterBtn> |
| | | <PageFooterBtn type="primary" @click="handleContact">立即联系</PageFooterBtn> |
| | | </template> |
| | | </JobDetailContent> |
| | | </LoadingLayout> |
| | |
| | | <script setup lang="ts"> |
| | | import Taro from '@tarojs/taro'; |
| | | import { useQuery } from '@tanstack/vue-query'; |
| | | import * as flexWorkerServices from '@12333/services/api/FlexWorker'; |
| | | import * as userResumeServices from '@12333/services/apiV2/userResume'; |
| | | import IconShare from '@/assets/flexJob/icon-share.png'; |
| | | import IconAttention from '@/assets/flexJob/icon-attention-lg.png'; |
| | | import IconAttentionActive from '@/assets/flexJob/icon-attention-lg-active.png'; |
| | | import { useToggle } from 'senin-mini/hooks'; |
| | | import { Message } from '@12333/utils'; |
| | | import { useUserResume } from '@12333/hooks'; |
| | | import { useAccessLogin } from '@/hooks'; |
| | | |
| | | defineOptions({ |
| | | name: 'flexJobDetail', |
| | | }); |
| | | |
| | | const router = Taro.useRouter(); |
| | | const taskId = router.params?.id ?? ''; |
| | | const enterpriseEmployeeId = router.params?.enterpriseEmployeeId ?? ''; |
| | | |
| | | const { |
| | | isLoading, |
| | | isError, |
| | | data: detail, |
| | | refetch, |
| | | } = useQuery({ |
| | | queryKey: ['flexWorkerServices/getOrdeForDetail', taskId], |
| | | queryFn: async () => { |
| | | return await flexWorkerServices.getOrdeForDetail( |
| | | { id: taskId }, |
| | | { |
| | | showLoading: false, |
| | | } |
| | | ); |
| | | }, |
| | | placeholderData: () => ({} as API.OrderInfoDto), |
| | | const { isLoading, isError, userResumeInfo, refetch } = useUserResume({ |
| | | userId: enterpriseEmployeeId, |
| | | }); |
| | | |
| | | const { isCollapse, toggle } = useToggle(); |
| | | |
| | | const handleContact = useAccessLogin(async () => { |
| | | try { |
| | | if (!isCollapse.value) { |
| | | await userResumeServices.contactUserResume({ id: enterpriseEmployeeId }); |
| | | toggle(); |
| | | } |
| | | } catch (error) {} |
| | | }); |
| | | |
| | | async function handleAttention() { |
| | | try { |
| | | let params: API.CollectFlexWorkerResumeInput = { |
| | | flexWorkerId: detail.value?.flexWorkerId, |
| | | userResumeId: detail.value?.userResumeId, |
| | | let params: API.CollectUserResumeCommand = { |
| | | id: enterpriseEmployeeId, |
| | | isCollected: !userResumeInfo.value.isCollected, |
| | | }; |
| | | let res = await flexWorkerServices.collectFlexWorkerResume(params); |
| | | let res = await userResumeServices.collectUserResume(params); |
| | | if (res) { |
| | | Message.success('收藏成功'); |
| | | refetch({ type: 'inactive' }); |
| | | } |
| | | } catch (error) {} |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | @import '@/styles/common.scss'; |
| | | </style> |
| | |
| | | <template> |
| | | <LoadingLayout :loading="isLoading" :error="isError" :loadError="refetch"> |
| | | <JobDetailContent :isCollapse="true"> |
| | | <JobDetailContent |
| | | :avatar="userResumeInfo.avatar" |
| | | :name="userResumeInfo.name" |
| | | :age="userResumeInfo.age" |
| | | :isReal="userResumeInfo.isReal" |
| | | :gender="userResumeInfo.gender" |
| | | :personalIdentityContent="userResumeInfo.personalIdentityContent" |
| | | :educationalBackgroundContent="userResumeInfo.educationalBackgroundContent" |
| | | :taskCount="userResumeInfo.taskCount" |
| | | :contactPhoneNumber="userResumeInfo.contactPhoneNumber" |
| | | :identity="userResumeInfo.identity" |
| | | :userId="enterpriseEmployeeId" |
| | | :userExpectJobs="userResumeInfo.userExpectJobs" |
| | | :freeTime="userResumeInfo.freeTime" |
| | | :jobSeekingStatus="userResumeInfo.jobSeekingStatus" |
| | | :userCredentials="userResumeInfo.userCredentials" |
| | | :workSeniority="userResumeInfo.workSeniority" |
| | | :workExperience="userResumeInfo.workExperience" |
| | | :photos="userResumeInfo.photos" |
| | | :height="userResumeInfo.height" |
| | | :weight="userResumeInfo.weight" |
| | | :taskInfoUsers="userResumeInfo.taskInfoUsers" |
| | | :isCollapse="true" |
| | | > |
| | | <template #footer> |
| | | <PageFooterBtn type="primary" plain @click="taskWorkerHireRefuse(10)">谢绝</PageFooterBtn> |
| | | <PageFooterBtn type="primary" @click="taskWorkerHireRefuse(20)">录用</PageFooterBtn> |
| | | <PageFooterBtn type="primary" plain @click="setTaskUserHire(EnumTaskUserHireStatus.Refuse)" |
| | | >谢绝</PageFooterBtn |
| | | > |
| | | <PageFooterBtn type="primary" @click="setTaskUserHire(EnumTaskUserHireStatus.Pass)" |
| | | >录用</PageFooterBtn |
| | | > |
| | | </template> |
| | | </JobDetailContent> |
| | | </LoadingLayout> |
| | |
| | | import { useQuery } from '@tanstack/vue-query'; |
| | | import * as taskUserServices from '@12333/services/apiV2/taskUser'; |
| | | import { Message } from '@12333/utils'; |
| | | import { useUserResume } from '@12333/hooks'; |
| | | import { EnumTaskUserHireStatus } from '@12333/constants'; |
| | | |
| | | defineOptions({ |
| | | name: 'InnerPage', |
| | | }); |
| | | |
| | | const router = Taro.useRouter(); |
| | | const enterpriseEmployeeId = router.params?.enterpriseEmployeeId ?? ''; |
| | | const id = router.params?.id ?? ''; |
| | | |
| | | const { |
| | | isLoading, |
| | | isError, |
| | | data: detail, |
| | | refetch, |
| | | } = useQuery({ |
| | | queryKey: ['taskServices/getTaskInfo', id], |
| | | queryFn: async () => { |
| | | return await taskServices.getTaskInfo( |
| | | { id: id }, |
| | | { |
| | | showLoading: false, |
| | | } |
| | | ); |
| | | }, |
| | | placeholderData: () => ({} as API.GetTaskInfoQueryResult), |
| | | const { isLoading, isError, userResumeInfo, refetch } = useUserResume({ |
| | | userId: enterpriseEmployeeId, |
| | | }); |
| | | |
| | | async function taskWorkerHireRefuse(hireStatus: FlexTaskWorkerHireEnum) { |
| | | async function setTaskUserHire(hireStatus: EnumTaskUserHireStatus) { |
| | | try { |
| | | let params: API.SetTaskUserHireCommand = { |
| | | id: id, |
| | |
| | | } catch (error) {} |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | @import '@/styles/common.scss'; |
| | | </style> |
| | |
| | | <template> |
| | | <LoadingLayout :loading="isLoading" :error="isError" :loadError="refetch"> |
| | | <JobDetailContent :isCollapse="true"> |
| | | <JobDetailContent |
| | | :avatar="userResumeInfo.avatar" |
| | | :name="userResumeInfo.name" |
| | | :age="userResumeInfo.age" |
| | | :isReal="userResumeInfo.isReal" |
| | | :gender="userResumeInfo.gender" |
| | | :personalIdentityContent="userResumeInfo.personalIdentityContent" |
| | | :educationalBackgroundContent="userResumeInfo.educationalBackgroundContent" |
| | | :taskCount="userResumeInfo.taskCount" |
| | | :contactPhoneNumber="userResumeInfo.contactPhoneNumber" |
| | | :identity="userResumeInfo.identity" |
| | | :userId="enterpriseEmployeeId" |
| | | :userExpectJobs="userResumeInfo.userExpectJobs" |
| | | :freeTime="userResumeInfo.freeTime" |
| | | :jobSeekingStatus="userResumeInfo.jobSeekingStatus" |
| | | :userCredentials="userResumeInfo.userCredentials" |
| | | :workSeniority="userResumeInfo.workSeniority" |
| | | :workExperience="userResumeInfo.workExperience" |
| | | :photos="userResumeInfo.photos" |
| | | :height="userResumeInfo.height" |
| | | :weight="userResumeInfo.weight" |
| | | :taskInfoUsers="userResumeInfo.taskInfoUsers" |
| | | :isCollapse="true" |
| | | > |
| | | <!-- <template #footer> |
| | | <PageFooterBtn type="primary" plain>解约</PageFooterBtn> |
| | | <PageFooterBtn type="primary">签约</PageFooterBtn> |
| | |
| | | <script setup lang="ts"> |
| | | import Taro from '@tarojs/taro'; |
| | | import { useQuery } from '@tanstack/vue-query'; |
| | | import * as flexWorkerServices from '@12333/services/api/FlexWorker'; |
| | | import { useUserResume } from '@12333/hooks'; |
| | | |
| | | defineOptions({ |
| | | name: 'InnerPage', |
| | | }); |
| | | |
| | | const router = Taro.useRouter(); |
| | | const taskId = router.params?.id ?? ''; |
| | | const enterpriseEmployeeId = router.params?.enterpriseEmployeeId ?? ''; |
| | | |
| | | const { |
| | | isLoading, |
| | | isError, |
| | | data: detail, |
| | | refetch, |
| | | } = useQuery({ |
| | | queryKey: ['flexWorkerServices/getOrdeForDetail', taskId], |
| | | queryFn: async () => { |
| | | return await flexWorkerServices.getOrdeForDetail( |
| | | { id: taskId }, |
| | | { |
| | | showLoading: false, |
| | | } |
| | | ); |
| | | }, |
| | | placeholderData: () => ({} as API.OrderInfoDto), |
| | | const { isLoading, isError, userResumeInfo, refetch } = useUserResume({ |
| | | userId: enterpriseEmployeeId, |
| | | }); |
| | | </script> |
| | | |
| | |
| | | |
| | | function goDetail(item: API.GetEnterpriseEmployeesQueryResultItem) { |
| | | Taro.navigateTo({ |
| | | url: `${RouterPath.flexJobDetailFromManage}?userId=${item.id}`, |
| | | url: `${RouterPath.flexJobDetailFromManage}?enterpriseEmployeeId=${item.id}`, |
| | | }); |
| | | } |
| | | |
| | |
| | | </div> |
| | | </template> |
| | | <template #footerRight> |
| | | <nut-button type="primary" @click="goToJobDetail(item.id)">查看详情</nut-button> |
| | | <nut-button type="primary" @click="goToJobDetail(item)">查看详情</nut-button> |
| | | </template> |
| | | </FlexJobCard> |
| | | </template> |
| | |
| | | id: id, |
| | | }); |
| | | |
| | | function goToJobDetail(id: string) { |
| | | function goToJobDetail(item: API.GetTaskUsersQueryResultItem) { |
| | | Taro.navigateTo({ |
| | | url: `${RouterPath.flexJobDetailFromTask}?id=${id}`, |
| | | url: `${RouterPath.flexJobDetailFromTask}?enterpriseEmployeeId=${item.enterpriseEmployeeId}&id=${item.id}`, |
| | | }); |
| | | } |
| | | </script> |
| | |
| | | return infiniteLoadingProps.value?.listData?.pages?.[0]?.objectData?.waitAssignCount ?? 0; |
| | | }); |
| | | |
| | | function goSubmitTaskDetail(item: API.GetTaskInfosQueryResultItem) { |
| | | Taro.navigateTo({ |
| | | url: `${RouterPath.flexJobDetail}?taskId=${item.id}`, |
| | | }); |
| | | } |
| | | //有问题 |
| | | // function goSubmitTaskDetail(item: API.GetTaskInfosQueryResultItem) { |
| | | // Taro.navigateTo({ |
| | | // url: `${RouterPath.taskManage}?taskId=${item.id}`, |
| | | // }); |
| | | // } |
| | | |
| | | function goBatchTaskList(item: API.GetTaskInfosQueryResultItem, status: EnumTaskUserArrangeStatus) { |
| | | Taro.navigateTo({ |
| | |
| | | const useSlots: typeof import('vue')['useSlots'] |
| | | const useSwitchTab: typeof import('./src/hooks/router')['useSwitchTab'] |
| | | const useTemplateRef: typeof import('vue')['useTemplateRef'] |
| | | const useUpdateResume: typeof import('./src/hooks/user')['useUpdateResume'] |
| | | const useUser: typeof import('./src/hooks/user')['useUser'] |
| | | const useUserResume: typeof import('./src/hooks/user')['useUserResume'] |
| | | const watch: typeof import('vue')['watch'] |
| | |
| | | readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']> |
| | | readonly useSwitchTab: UnwrapRef<typeof import('./src/hooks/router')['useSwitchTab']> |
| | | readonly useTemplateRef: UnwrapRef<typeof import('vue')['useTemplateRef']> |
| | | readonly useUpdateResume: UnwrapRef<typeof import('./src/hooks/user')['useUpdateResume']> |
| | | readonly useUser: UnwrapRef<typeof import('./src/hooks/user')['useUser']> |
| | | readonly useUserResume: UnwrapRef<typeof import('./src/hooks/user')['useUserResume']> |
| | | readonly watch: UnwrapRef<typeof import('vue')['watch']> |
| | |
| | | import { MaybeRef } from 'vue'; |
| | | import { useRefeshDidShow } from '@12333/hooks/infiniteLoading'; |
| | | import * as userResumeServices from '@12333/services/apiV2/userResume'; |
| | | import { useUserResume as useUserResumeHook } from '@12333/hooks'; |
| | | |
| | | export function useUser() { |
| | | const userStore = useUserStore(); |
| | |
| | | |
| | | export function useUserResume() { |
| | | const { userId } = useUser(); |
| | | |
| | | const { data, refetch } = useQuery({ |
| | | queryKey: ['userResumeServices/getUserResume', userId], |
| | | queryFn: async () => { |
| | | return await userResumeServices.getUserResume( |
| | | { userId: userId.value }, |
| | | { |
| | | showLoading: false, |
| | | } |
| | | ); |
| | | }, |
| | | placeholderData: () => ({} as API.GetUserResumeQueryResult), |
| | | enabled: computed(() => !!userId.value), |
| | | }); |
| | | |
| | | return { |
| | | userResumeInfo: data, |
| | | refetch, |
| | | }; |
| | | } |
| | | |
| | | export function useUpdateResume() { |
| | | const queryClient = useQueryClient(); |
| | | |
| | | const updateUserResumeCredentials = () => { |
| | | return queryClient.invalidateQueries({ |
| | | queryKey: ['userResumeServices/getUserResumeCredentials'], |
| | | }); |
| | | }; |
| | | |
| | | const updateUserResume = () => { |
| | | return queryClient.invalidateQueries({ |
| | | queryKey: ['userResumeServices/getUserResume'], |
| | | }); |
| | | }; |
| | | |
| | | return { |
| | | updateUserResumeCredentials, |
| | | updateUserResume, |
| | | }; |
| | | return useUserResumeHook({ userId }); |
| | | } |
| | |
| | | import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types'; |
| | | import { ChooseInputWithPicker, ChooseInputWithAreaPicker } from '@12333/components'; |
| | | import { convertApi2FormUrlOnlyOne, Message, setOSSLink } from '@12333/utils'; |
| | | import { useAreaTree, useDictionaryDataSelect } from '@12333/hooks'; |
| | | import { useAreaTree, useDictionaryDataSelect, useUpdateResume } from '@12333/hooks'; |
| | | import { AreaType, CategoryCode } from '@12333/constants'; |
| | | import * as userResumeServices from '@12333/services/apiV2/userResume'; |
| | | import Taro from '@tarojs/taro'; |
| | |
| | | import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types'; |
| | | import { useQuery, useQueryClient } from '@tanstack/vue-query'; |
| | | import Taro from '@tarojs/taro'; |
| | | import { useDictionaryDataSelect } from '@12333/hooks'; |
| | | import { useDictionaryDataSelect, useUpdateResume } from '@12333/hooks'; |
| | | import { CategoryCode } from '@12333/constants'; |
| | | import { convertApi2FormUrlOnlyOne, Message, setOSSLink, FormValidator } from '@12333/utils'; |
| | | import dayjs from 'dayjs'; |
| | |
| | | <script setup lang="ts"> |
| | | import { goBack } from '@/utils'; |
| | | import { NumberInput } from '@12333/components'; |
| | | import { useUpdateResume } from '@12333/hooks'; |
| | | import * as userResumeServices from '@12333/services/apiV2/userResume'; |
| | | import { convertApiPath2Url, Message } from '@12333/utils'; |
| | | import { FileItem } from '@nutui/nutui-taro/dist/types/__VUE/uploader/type'; |
| | |
| | | } from '@12333/constants'; |
| | | import Taro from '@tarojs/taro'; |
| | | import * as userResumeServices from '@12333/services/apiV2/userResume'; |
| | | import { useDictionaryDataSelect } from '@12333/hooks'; |
| | | import { useDictionaryDataSelect, useUpdateResume } from '@12333/hooks'; |
| | | import { Message } from '@12333/utils'; |
| | | import { useQuery } from '@tanstack/vue-query'; |
| | | import { goBack } from '@/utils'; |
| | |
| | | |
| | | <script setup lang="ts"> |
| | | import { goBack } from '@/utils'; |
| | | import { useUpdateResume } from '@12333/hooks'; |
| | | import * as userResumeServices from '@12333/services/apiV2/userResume'; |
| | | import { Message } from '@12333/utils'; |
| | | import { useQuery } from '@tanstack/vue-query'; |
| | |
| | | {{ workExperience }} |
| | | </div> |
| | | <div class="flexJob-card-done-detail" v-if="showDoneDetail"> |
| | | <div class="flexJob-card-done-detail-item"> |
| | | {{ workSeniority }} |
| | | </div> |
| | | <div class="flexJob-card-done-detail-item">{{ workSeniority }}年</div> |
| | | <!-- <div class="flexJob-card-done-detail-item">{{ '在「宁波雷迪森酒店」,做过客房服务员' }}</div> --> |
| | | </div> |
| | | <div class="flexJob-card-footer"> |
| | |
| | | export * from './enterprise'; |
| | | export * from './task'; |
| | | export * from './taskUser'; |
| | | export * from './user'; |
New file |
| | |
| | | import { MaybeRef, computed, unref } from 'vue'; |
| | | import * as userResumeServices from '@12333/services/apiV2/userResume'; |
| | | import { useQuery, useQueryClient } from '@tanstack/vue-query'; |
| | | |
| | | type UseUserResumeOptions = { |
| | | userId: MaybeRef<string>; |
| | | }; |
| | | |
| | | export function useUserResume({ userId }: UseUserResumeOptions) { |
| | | const { data, refetch, isLoading, isError } = useQuery({ |
| | | queryKey: ['userResumeServices/getUserResume', userId], |
| | | queryFn: async () => { |
| | | return await userResumeServices.getUserResume( |
| | | { userId: unref(userId) }, |
| | | { |
| | | showLoading: false, |
| | | } |
| | | ); |
| | | }, |
| | | placeholderData: () => ({} as API.GetUserResumeQueryResult), |
| | | enabled: computed(() => !!unref(userId)), |
| | | }); |
| | | |
| | | return { |
| | | userResumeInfo: data, |
| | | refetch, |
| | | isLoading, |
| | | isError, |
| | | }; |
| | | } |
| | | |
| | | export function useUpdateResume() { |
| | | const queryClient = useQueryClient(); |
| | | |
| | | const updateUserResumeCredentials = () => { |
| | | return queryClient.invalidateQueries({ |
| | | queryKey: ['userResumeServices/getUserResumeCredentials'], |
| | | }); |
| | | }; |
| | | |
| | | const updateUserResume = () => { |
| | | return queryClient.invalidateQueries({ |
| | | queryKey: ['userResumeServices/getUserResume'], |
| | | }); |
| | | }; |
| | | |
| | | return { |
| | | updateUserResumeCredentials, |
| | | updateUserResume, |
| | | }; |
| | | } |
| | |
| | | // @ts-ignore |
| | | import { request } from '@/utils/request'; |
| | | |
| | | /** 编辑灵工信息 POST /api/user/enterpriseEmployee/editEnterpriseEmployee */ |
| | | export async function editEnterpriseEmployee( |
| | | body: API.EditEnterpriseEmployeeCommand, |
| | | options?: API.RequestConfig |
| | | ) { |
| | | return request<string>('/api/user/enterpriseEmployee/editEnterpriseEmployee', { |
| | | method: 'POST', |
| | | headers: { |
| | | 'Content-Type': 'application/json-patch+json', |
| | | }, |
| | | data: body, |
| | | ...(options || {}), |
| | | }); |
| | | } |
| | | |
| | | /** 查询灵工详情 GET /api/user/enterpriseEmployee/getEnterpriseEmployee */ |
| | | export async function getEnterpriseEmployee( |
| | | // 叠加生成的Param类型 (非body参数swagger默认没有生成对象) |
| | |
| | | } |
| | | ); |
| | | } |
| | | |
| | | /** 导入灵工信息 POST /api/user/enterpriseEmployee/importEnterpriseEmployees */ |
| | | export async function importEnterpriseEmployees( |
| | | body: API.ImportEnterpriseEmployeesCommand, |
| | | options?: API.RequestConfig |
| | | ) { |
| | | return request<number>('/api/user/enterpriseEmployee/importEnterpriseEmployees', { |
| | | method: 'POST', |
| | | headers: { |
| | | 'Content-Type': 'application/json-patch+json', |
| | | }, |
| | | data: body, |
| | | ...(options || {}), |
| | | }); |
| | | } |
| | |
| | | ids: string[]; |
| | | } |
| | | |
| | | interface EditEnterpriseEmployeeCommand { |
| | | /** 灵工Id */ |
| | | id?: string; |
| | | /** 姓名 */ |
| | | name?: string; |
| | | /** 身份证号 */ |
| | | identity?: string; |
| | | /** 手机号 */ |
| | | contactPhoneNumber?: string; |
| | | gender?: EnumUserGender; |
| | | /** 年龄 */ |
| | | age?: number; |
| | | /** 身份证人像面 */ |
| | | identityImg?: string; |
| | | /** 身份证国徽面 */ |
| | | identityBackImg?: string; |
| | | } |
| | | |
| | | enum EnumBillingMethod { |
| | | /**按月 */ |
| | | Month = 10, |
| | |
| | | releaseStatus?: EnumTaskReleaseStatus; |
| | | recommendStatus?: EnumTaskRecommendStatus; |
| | | checkReceiveStatus?: EnumTaskCheckReceiveStatus; |
| | | /** 是否收藏 */ |
| | | isCollected?: boolean; |
| | | pageModel?: PagedListQueryPageModel; |
| | | } |
| | | |
| | |
| | | photos?: string[]; |
| | | /** 经历 */ |
| | | taskInfoUsers?: GetUserResumeQueryResultExperience[]; |
| | | /** 是否已收藏 */ |
| | | isCollected?: boolean; |
| | | } |
| | | |
| | | interface GetUserResumeQueryResultCredential { |
| | |
| | | ageMax?: number; |
| | | /** 资格证书编号 */ |
| | | userCredentials?: string[]; |
| | | /** 是否已收藏 */ |
| | | isCollected?: boolean; |
| | | /** 是否已联系 */ |
| | | isContacted?: boolean; |
| | | pageModel?: PagedListQueryPageModel; |
| | | } |
| | | |
| | |
| | | workSeniority?: string; |
| | | /** 工作经验 */ |
| | | workExperience?: string; |
| | | /** 创建时间 */ |
| | | createdTime?: string; |
| | | } |
| | | |
| | | type GetUserResumeWorkExperienceQuery = Record<string, any>; |
| | |
| | | workExperience?: string; |
| | | } |
| | | |
| | | interface ImportEnterpriseEmployeesCommand { |
| | | /** Excel地址 */ |
| | | excelUrl?: string; |
| | | } |
| | | |
| | | interface LoginCommandCallback { |
| | | /** 用户Id */ |
| | | id?: string; |
| | |
| | | return list.filter(Boolean).join(separator); |
| | | } |
| | | |
| | | export const hiddenIDNumberForEnd6 = (realIDNumber: string) => |
| | | export const hiddenIDNumberForEnd6 = (realIDNumber: string) => { |
| | | if (!realIDNumber) return ''; |
| | | realIDNumber.replace(/^(\d+)(.{6})$/, '$1******'); |
| | | }; |