| | |
| | | <QueryMenuView @close="handleReset" @confirm="emit('close')" cancelText="重置"> |
| | | <div class="home-query-menu-view"> |
| | | <QueryMenuItem title="性别"> |
| | | <ProRadio v-model="query.gender" :value-enum="GenderText" show-all-btn></ProRadio> |
| | | <ProRadio |
| | | v-model="query.genderLimit" |
| | | :value-enum="EnumUserGenderText" |
| | | show-all-btn |
| | | ></ProRadio> |
| | | </QueryMenuItem> |
| | | <QueryMenuItem title="身份"> |
| | | <ProRadio v-model="query.identity" :value-enum="identityList" show-all-btn></ProRadio> |
| | |
| | | |
| | | <script setup lang="ts"> |
| | | import { QueryMenuView, QueryMenuItem, ProRadio } from '@12333/components'; |
| | | import { GenderText, CategoryCode } from '@12333/constants'; |
| | | import { EnumUserGenderText, CategoryCode } from '@12333/constants'; |
| | | import { useDictionaryDataSelect } from '@12333/hooks'; |
| | | |
| | | defineOptions({ |
| | |
| | | }>(); |
| | | |
| | | const query = defineModel<{ |
| | | gender: number | string; |
| | | genderLimit: number | string; |
| | | age: number[]; |
| | | identity: string; |
| | | certificateType: string; |
| | |
| | | import { ProTabs, ProTabPane, FlexJobCard } from '@12333/components'; |
| | | import { HomeOrderType } from './constants'; |
| | | import { useInfiniteLoading } from '@12333/hooks'; |
| | | import { OrderInputType, Gender } from '@12333/constants'; |
| | | import * as flexWorkerServices from '@12333/services/api/FlexWorker'; |
| | | import { |
| | | EnumPagedListOrder, |
| | | EnumTaskRecommendStatus, |
| | | 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'; |
| | |
| | | const userStore = useUserStore(); |
| | | |
| | | const queryMenuState = reactive({ |
| | | gender: '' as any as Gender, |
| | | genderLimit: '' as any as EnumUserGender, |
| | | age: [15, 65], |
| | | identity: '', |
| | | certificateType: '', |
| | |
| | | |
| | | const { infiniteLoadingProps } = useInfiniteLoading( |
| | | ({ pageParam }) => { |
| | | let params: API.GetFlexTaskListInput = { |
| | | let params: API.GetTaskInfosQuery = { |
| | | pageModel: { |
| | | rows: 20, |
| | | page: pageParam, |
| | | orderInput: [{ property: 'taskId', order: OrderInputType.Desc }], |
| | | orderInput: [ |
| | | queryState.orderType === HomeOrderType.Recommend |
| | | ? { 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, |
| | | }; |
| | | |
| | | return flexWorkerServices.getFlexTaskWorkerArrangeList(params, { |
| | | if (queryState.orderType === HomeOrderType.Recommend) { |
| | | params.recommendStatus = EnumTaskRecommendStatus.Yes; |
| | | } |
| | | |
| | | return taskServices.getTaskInfos(params, { |
| | | showLoading: false, |
| | | }); |
| | | }, |
| | | { |
| | | queryKey: [ |
| | | 'flexWorkerServices/getFlexTaskByArrange', |
| | | queryState, |
| | | queryMenuState, |
| | | queryPositionState, |
| | | ], |
| | | queryKey: ['taskServices/getTaskInfos', queryState, queryMenuState, queryPositionState], |
| | | } |
| | | ); |
| | | |
| | |
| | | </nut-form-item> |
| | | <nut-form-item label=" " class="bole-form-item" prop="serviceFee" label-width="0"> |
| | | <div class="bole-form-input-wrapper"> |
| | | <nut-input |
| | | <NumberInput |
| | | v-model.trim="form.serviceFee" |
| | | class="nut-input-text bole-input-text" |
| | | placeholder="请输入服务费" |
| | | type="text" |
| | | :min="0" |
| | | /> |
| | | <div class="form-input-unit">{{ BillingMethodEnumUnit[form.billingMethod] }}</div> |
| | | </div> |
| | |
| | | <ChooseInputWithPicker |
| | | v-model="form.genderLimit" |
| | | placeholder="请选择性别要求" |
| | | :value-enum="EnumUserGenderText" |
| | | :value-enum="EnumUserGenderTextOptions" |
| | | /> |
| | | </nut-form-item> |
| | | <nut-form-item |
| | |
| | | prop="beginTime" |
| | | label-width="90px" |
| | | > |
| | | <ChooseInputWithDatePicker v-model="form.beginTime"></ChooseInputWithDatePicker> |
| | | <ChooseInputWithDatePicker |
| | | v-model="form.beginTime" |
| | | :minDate="nowDate" |
| | | ></ChooseInputWithDatePicker> |
| | | </nut-form-item> |
| | | <nut-form-item label="任务结束日期:" class="bole-form-item" prop="endTime" label-width="90px"> |
| | | <ChooseInputWithDatePicker v-model="form.endTime"></ChooseInputWithDatePicker> |
| | | <ChooseInputWithDatePicker |
| | | v-model="form.endTime" |
| | | :minDate="nowDate" |
| | | ></ChooseInputWithDatePicker> |
| | | </nut-form-item> |
| | | </nut-form> |
| | | </ContentScrollView> |
| | |
| | | EnumUserGenderText, |
| | | EnumSettlementCycleText, |
| | | BillingMethodEnumUnit, |
| | | EnumUserGenderTextOptions, |
| | | } from '@12333/constants'; |
| | | import { |
| | | ChooseInputWithPicker, |
| | |
| | | const isEdit = !!taskId; |
| | | const isCopy = router.params?.isCopy === 'true'; |
| | | console.log('isCopy: ', router.params?.isCopy); |
| | | |
| | | const nowDate = dayjs().toDate(); |
| | | |
| | | const { dictionaryDataList: WelfareTypeList } = useDictionaryDataSelect({ |
| | | categoryCode: CategoryCode.Welfare, |
| | |
| | | } |
| | | |
| | | function handleCancel() { |
| | | Taro.navigateBack(); |
| | | goBack(); |
| | | } |
| | | </script> |
| | | |
| | |
| | | const errorInfo: ErrorInfo | undefined = (error as any).info; |
| | | if (errorInfo) { |
| | | const { errorMessage, errorCode } = errorInfo; |
| | | if (Number(errorCode) === 401) { |
| | | handleLogout(); |
| | | } |
| | | switch (errorInfo.showType) { |
| | | case ErrorShowType.SILENT: |
| | | // do nothing |
| | |
| | | } else if ((error as AxiosError<ResponseStructure, IRequestOptions>).response) { |
| | | // Axios 的错误 |
| | | // 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围 |
| | | handleAxiosResponseError(error as AxiosError<ErrorResponse, IRequestOptions>); |
| | | handleAxiosResponseError(error as AxiosError<ResponseStructure, IRequestOptions>); |
| | | // Message.errorMessage(`Response status:${(error as AxiosError).response.status}`); |
| | | } else if ((error as AxiosError).request) { |
| | | // 请求已经成功发起,但没有收到响应 |
| | |
| | | [505]: 'HTTP版本不受支持', |
| | | }; |
| | | |
| | | function handleAxiosResponseError(error: AxiosError<ErrorResponse, IRequestOptions>) { |
| | | function handleAxiosResponseError(error: AxiosError<ResponseStructure, IRequestOptions>) { |
| | | if (error.response.config.url.toLowerCase().includes(RefreshTokenUrl.toLowerCase())) { |
| | | handleLogout(); |
| | | return; |
| | | } |
| | | if (error && error.response) { |
| | | let message = ErrorMessageMap[error.response?.status] ?? '请求错误'; |
| | | if (error.response.data?.error?.message) { |
| | | message = error.response.data?.error?.message; |
| | | if (error.response.data?.msg) { |
| | | message = error.response.data?.msg; |
| | | } |
| | | if (error.response?.status === 401) { |
| | | if (error.response?.status === 401 || error.response.data.code === 401) { |
| | | handleLogout(); |
| | | } |
| | | |
| | |
| | | import { useInfiniteLoading } from '@12333/hooks'; |
| | | import { OrderInputType, Gender } from '@12333/constants'; |
| | | import * as flexWorkerServices from '@12333/services/api/FlexWorker'; |
| | | import { |
| | | EnumPagedListOrder, |
| | | EnumSettlementCycle, |
| | | EnumTaskRecommendStatus, |
| | | EnumTaskReleaseStatus, |
| | | EnumTaskStatus, |
| | | EnumUserGender, |
| | | } from '@12333/constants'; |
| | | import _ from 'lodash'; |
| | | import { trim } from '@12333/utils'; |
| | | import { MaybeRef } from 'vue'; |
| | | import * as taskServices from '@12333/services/apiV2/task'; |
| | | |
| | | export enum HomeOrderType { |
| | | Recommend = 'Recommend', |
| | |
| | | const searchValue = ref(''); |
| | | |
| | | const queryMenuState = reactive({ |
| | | gender: '' as any as Gender, |
| | | genderLimit: '' as any as EnumUserGender, |
| | | settlementCycle: '' as any as EnumSettlementCycle, |
| | | benefitCodes: '', |
| | | status: '' as any as EnumTaskStatus, |
| | | }); |
| | | |
| | | const queryState = reactive({ |
| | | searchValueTrim: '', |
| | | orderType: HomeOrderType.Recommend, |
| | | companyId: '', |
| | | }); |
| | | |
| | | const handleSearch = _.debounce(function () { |
| | |
| | | |
| | | const { infiniteLoadingProps } = useInfiniteLoading( |
| | | ({ pageParam }) => { |
| | | let params: API.GetFlexTaskListInput = { |
| | | let params: API.GetTaskInfosQuery = { |
| | | pageModel: { |
| | | rows: 20, |
| | | page: pageParam, |
| | | orderInput: [ |
| | | queryState.orderType === HomeOrderType.Recommend |
| | | ? { property: 'creationTime', order: OrderInputType.Desc } |
| | | : { property: 'lastShelfTime', order: OrderInputType.Desc }, |
| | | ? { property: 'createdTime', order: EnumPagedListOrder.Desc } |
| | | : {}, |
| | | ], |
| | | }, |
| | | keywords: queryState.searchValueTrim, |
| | | // cityCode: 'string', |
| | | settlementCycle: queryMenuState.settlementCycle, |
| | | benefitCodes: [queryMenuState.benefitCodes].filter(Boolean), |
| | | genderLimit: queryMenuState.genderLimit, |
| | | status: queryMenuState.status, |
| | | releaseStatus: EnumTaskReleaseStatus.InProcess, |
| | | }; |
| | | |
| | | return flexWorkerServices.getFlexTaskByArrange(params, { |
| | | if (queryState.orderType === HomeOrderType.Recommend) { |
| | | params.recommendStatus = EnumTaskRecommendStatus.Yes; |
| | | } |
| | | |
| | | return taskServices.getTaskInfos(params, { |
| | | showLoading: false, |
| | | }); |
| | | }, |
| | | { |
| | | queryKey: ['flexWorkerServices/getFlexTaskByArrange', queryState, queryMenuState, cityName], |
| | | queryKey: ['taskServices/getTaskInfos', queryState, queryMenuState, cityName], |
| | | } |
| | | ); |
| | | |
| | |
| | | <div class="home-query-menu-view"> |
| | | <QueryMenuItem title="结算方式"> |
| | | <ProRadio |
| | | v-model="query.gender" |
| | | :value-enum="FlexTaskSettleTypeEnumText" |
| | | v-model="query.settlementCycle" |
| | | :value-enum="EnumSettlementCycleText" |
| | | show-all-btn |
| | | ></ProRadio> |
| | | </QueryMenuItem> |
| | | <QueryMenuItem title="员工福利"> |
| | | <ProRadio v-model="query.gender" :value-enum="WelfareList" show-all-btn></ProRadio> |
| | | <!-- <ProRadio v-model="query.benefitCodes" :value-enum="welfareList" show-all-btn></ProRadio> --> |
| | | </QueryMenuItem> |
| | | <QueryMenuItem title="性别要求"> |
| | | <ProRadio v-model="query.gender" :value-enum="GenderText" show-all-btn></ProRadio> |
| | | <ProRadio |
| | | v-model="query.genderLimit" |
| | | :value-enum="EnumUserGenderText" |
| | | show-all-btn |
| | | ></ProRadio> |
| | | </QueryMenuItem> |
| | | </div> |
| | | </QueryMenuView> |
| | |
| | | |
| | | <script setup lang="ts"> |
| | | import { QueryMenuView, QueryMenuItem, ProRadio } from '@12333/components'; |
| | | import { GenderText, SearchType, FlexTaskSettleTypeEnumText } from '@12333/constants'; |
| | | import { useSearchSettingType } from '@12333/hooks'; |
| | | import { |
| | | EnumUserGenderText, |
| | | EnumSettlementCycle, |
| | | CategoryCode, |
| | | EnumSettlementCycleText, |
| | | } from '@12333/constants'; |
| | | import { useDictionaryDataSelect } from '@12333/hooks'; |
| | | |
| | | defineOptions({ |
| | | name: 'HomeQueryMenuView', |
| | |
| | | |
| | | // const props = withDefaults(defineProps<Props>(), {}); |
| | | |
| | | const { searchSettingTypeList: WelfareList } = useSearchSettingType({ |
| | | searchType: SearchType.Welfare, |
| | | const { dictionaryDataList: welfareList } = useDictionaryDataSelect({ |
| | | categoryCode: CategoryCode.Welfare, |
| | | }); |
| | | |
| | | const emit = defineEmits<{ |
| | |
| | | }>(); |
| | | |
| | | const query = defineModel<{ |
| | | gender: number | string; |
| | | genderLimit: number | string; |
| | | settlementCycle: EnumSettlementCycle; |
| | | benefitCodes: string; |
| | | }>('query'); |
| | | |
| | | const DefaultQuery = { |
| | |
| | | <div class="city-btn-text">{{ locationCity }}</div> |
| | | </div> |
| | | </div> |
| | | <div class="home-banner-wrapper"> |
| | | <!-- <div class="home-banner-wrapper"> |
| | | <nut-swiper :auto-play="3000"> |
| | | <nut-swiper-item v-for="(item, index) in list" :key="index"> |
| | | <img :src="item" class="banner-img" draggable="false" /> |
| | | </nut-swiper-item> |
| | | </nut-swiper> |
| | | </div> |
| | | </div> --> |
| | | </div> |
| | | <ProTabs |
| | | v-model="queryState.orderType" |
| | |
| | | const errorInfo: ErrorInfo | undefined = (error as any).info; |
| | | if (errorInfo) { |
| | | const { errorMessage, errorCode } = errorInfo; |
| | | if (Number(errorCode) === 401) { |
| | | handleLogout(); |
| | | } |
| | | switch (errorInfo.showType) { |
| | | case ErrorShowType.SILENT: |
| | | // do nothing |
| | |
| | | } else if ((error as AxiosError<ResponseStructure, IRequestOptions>).response) { |
| | | // Axios 的错误 |
| | | // 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围 |
| | | handleAxiosResponseError(error as AxiosError<ErrorResponse, IRequestOptions>); |
| | | handleAxiosResponseError(error as AxiosError<ResponseStructure, IRequestOptions>); |
| | | // Message.errorMessage(`Response status:${(error as AxiosError).response.status}`); |
| | | } else if ((error as AxiosError).request) { |
| | | // 请求已经成功发起,但没有收到响应 |
| | |
| | | [505]: 'HTTP版本不受支持', |
| | | }; |
| | | |
| | | function handleAxiosResponseError(error: AxiosError<ErrorResponse, IRequestOptions>) { |
| | | function handleAxiosResponseError(error: AxiosError<ResponseStructure, IRequestOptions>) { |
| | | if (error.response.config.url.toLowerCase().includes(RefreshTokenUrl.toLowerCase())) { |
| | | handleLogout(); |
| | | return; |
| | | } |
| | | if (error && error.response) { |
| | | let message = ErrorMessageMap[error.response?.status] ?? '请求错误'; |
| | | if (error.response.data?.error?.message) { |
| | | message = error.response.data?.error?.message; |
| | | if (error.response.data?.msg) { |
| | | message = error.response.data?.msg; |
| | | } |
| | | if (error.response?.status === 401) { |
| | | if (error.response?.status === 401 || error.response.data.code === 401) { |
| | | handleLogout(); |
| | | } |
| | | |
| | |
| | | |
| | | type Props = { |
| | | modelValue: string | number; |
| | | minDate?: Date; |
| | | }; |
| | | |
| | | const props = withDefaults(defineProps<Props>(), {}); |
| | |
| | | emit('update:modelValue', dayjs(selectedValue).format('YYYY-MM-DD')); |
| | | onClose(); |
| | | }, |
| | | minDate: props.minDate, |
| | | }), |
| | | } |
| | | ), |
| | |
| | | |
| | | const props = withDefaults(defineProps<Props>(), { |
| | | enumLabelKey: 'label', |
| | | enumValueKey: 'code', |
| | | enumValueKey: 'value', |
| | | }); |
| | | |
| | | const emit = defineEmits<{ |
| | |
| | | }; |
| | | |
| | | export const EnumUserGenderText = { |
| | | [EnumUserGender.Male]: '男', |
| | | [EnumUserGender.Female]: '女', |
| | | [EnumUserGender.Male]: '仅限男性', |
| | | [EnumUserGender.Female]: '仅限女性', |
| | | }; |
| | | |
| | | export const EnumUserGenderTextOptions = { |
| | | [0]: '不限', |
| | | [EnumUserGender.Male]: '仅限男性', |
| | | [EnumUserGender.Female]: '仅限女性', |
| | | }; |
| | | |
| | | export const EnumSettlementCycleText = { |