| | |
| | | benefits: [] as string[], |
| | | ageMinLimit: 0, |
| | | ageMaxLimit: 0, |
| | | genderLimit: '' as any as EnumUserGender, |
| | | genderLimit: 0 as any as EnumUserGender, |
| | | credentialLimits: [] as string[], |
| | | // address: '', |
| | | beginTime: '', |
| | |
| | | } |
| | | |
| | | type UseTaskListOptions = { |
| | | cityName?: MaybeRef<string>; |
| | | cityCode?: MaybeRef<string>; |
| | | enabled?: MaybeRef<boolean>; |
| | | }; |
| | | |
| | | export function useTaskList(options: UseTaskListOptions = {}) { |
| | | const { cityName = '' } = options; |
| | | const { cityCode = '', enabled = true } = options; |
| | | |
| | | const searchValue = ref(''); |
| | | |
| | |
| | | ], |
| | | }, |
| | | keywords: queryState.searchValueTrim, |
| | | // cityCode: 'string', |
| | | cityCode: unref(cityCode), |
| | | settlementCycle: queryMenuState.settlementCycle, |
| | | benefitCodes: [queryMenuState.benefitCodes].filter(Boolean), |
| | | genderLimit: queryMenuState.genderLimit, |
| | |
| | | }); |
| | | }, |
| | | { |
| | | queryKey: ['taskServices/getTaskInfos', queryState, queryMenuState, cityName], |
| | | queryKey: ['taskServices/getTaskInfos', queryState, queryMenuState, cityCode], |
| | | enabled: enabled, |
| | | } |
| | | ); |
| | | |
| | |
| | | :key="queryState.orderType" |
| | | > |
| | | <template #renderItem="{ item }"> |
| | | <TaskCard @click="goTaskDetail(item)" v-bind="item" /> |
| | | <TaskCard @click="goTaskDetail(item)" v-bind="item" @apply="goTaskApply(item)" /> |
| | | </template> |
| | | </InfiniteLoading> |
| | | </PageLayoutWithBg> |
| | |
| | | import { TaskCard, ProTabs, ProTabPane } from '@12333/components'; |
| | | import HomeQueryMenuView from './HomeQueryMenuView.vue'; |
| | | import IconLocaltion from '@/assets/task/icon-localtion.png'; |
| | | import { useAllAreaList } from '@12333/hooks'; |
| | | import { useAccessLogin } from '@/hooks'; |
| | | |
| | | const { locationCity } = useUser(); |
| | | |
| | | const userStore = useUserStore(); |
| | | const { findAreaCodeFromName } = useAllAreaList(); |
| | | |
| | | const { searchValue, queryState, handleSearch, infiniteLoadingProps, queryMenuState } = useTaskList( |
| | | { cityName: locationCity } |
| | | { |
| | | cityCode: computed(() => findAreaCodeFromName(locationCity.value)), |
| | | enabled: computed(() => !!findAreaCodeFromName(locationCity.value)), |
| | | } |
| | | ); |
| | | |
| | | onMounted(async () => { |
| | |
| | | url: `${RouterPath.taskDetail}?id=${item.id}`, |
| | | }); |
| | | } |
| | | |
| | | const goTaskApply = useAccessLogin((item: API.GetTaskInfosQueryResultItem) => { |
| | | console.log('item: ', item); |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | |
| | | </div> --> |
| | | </div> |
| | | <TaskPrice |
| | | :value="detail.serviceFee ?? 0" |
| | | :value="toThousand(detail.serviceFee ?? 0)" |
| | | :unit="BillingMethodEnumUnit[detail.billingMethod]" |
| | | /> |
| | | </div> |
| | |
| | | openType="share" |
| | | ></PageFooterAction> |
| | | <PageFooterAction :icon="IconPhone" text="手机" :isFlex="false"></PageFooterAction> |
| | | <PageFooterBtn type="primary">报名(5人已报名)</PageFooterBtn> |
| | | <PageFooterBtn v-if="detail.releaseStatus === EnumTaskReleaseStatus.InProcess" type="primary" |
| | | >报名(5人已报名)</PageFooterBtn |
| | | > |
| | | <PageFooterBtn v-if="detail.releaseStatus === EnumTaskReleaseStatus.Stopped" color="#999999" |
| | | >已停止</PageFooterBtn |
| | | > |
| | | </PageFooter> |
| | | </LoadingLayout> |
| | | </template> |
| | |
| | | import './taskDetail.scss'; |
| | | import CompanyDesc from '../components/CompanyDesc.vue'; |
| | | import dayjs from 'dayjs'; |
| | | import { TaskUtils } from '@12333/utils'; |
| | | import { EnumSettlementCycleText, BillingMethodEnumUnit } from '@12333/constants'; |
| | | import { TaskUtils, toThousand } from '@12333/utils'; |
| | | import { |
| | | EnumSettlementCycleText, |
| | | BillingMethodEnumUnit, |
| | | EnumTaskReleaseStatus, |
| | | } from '@12333/constants'; |
| | | import { useAccessLogin } from '@/hooks'; |
| | | |
| | | defineOptions({ |
| | |
| | | }); |
| | | |
| | | /** |
| | | * TODO 缺少已报名人数 手机 投诉举报接口 |
| | | * TODO 缺少已报名人数 手机 投诉举报接口 报名接口 |
| | | */ |
| | | |
| | | const router = Taro.useRouter(); |
| | |
| | | <div class="task-card-title-wrapper"> |
| | | <div class="task-card-title">{{ name }}</div> |
| | | <slot name="title-right"> |
| | | <TaskPrice :value="serviceFee ?? 0" :unit="BillingMethodEnumUnit[billingMethod]" /> |
| | | <TaskPrice |
| | | :value="toThousand(serviceFee ?? 0)" |
| | | :unit="BillingMethodEnumUnit[billingMethod]" |
| | | /> |
| | | </slot> |
| | | </div> |
| | | <slot> |
| | |
| | | {{ EnumSettlementCycleText[settlementCycle] }} |
| | | </div> |
| | | <div class="task-card-welfare-list-item">{{ TaskUtils.getGenderText(genderLimit) }}</div> |
| | | <div class="task-card-welfare-list-item">包三餐</div> |
| | | <div |
| | | class="task-card-welfare-list-item" |
| | | v-if="benefits?.length > 0" |
| | | v-for="item in benefits" |
| | | :key="item.benefitCode" |
| | | > |
| | | {{ item.benefitContent }} |
| | | </div> |
| | | </div> |
| | | <div class="task-card-time"> |
| | | {{ dayjs(beginTime).format('YYYY年MM月DD日') }}至{{ |
| | |
| | | <div class="task-card-footer"> |
| | | <div class="task-card-left"> |
| | | <div class="task-card-footer-tag">H</div> |
| | | <div class="task-card-footer-address">{{ 'address' }}</div> |
| | | <div class="task-card-footer-address">{{ addressName }}</div> |
| | | </div> |
| | | <div class="task-card-actions" v-if="showActions"> |
| | | <slot name="actions"> |
| | | <nut-button type="primary" @click.stop="handleSign">报名</nut-button> |
| | | <nut-button |
| | | v-if="releaseStatus === EnumTaskReleaseStatus.InProcess" |
| | | type="primary" |
| | | @click.stop="emit('apply', id)" |
| | | >报名</nut-button |
| | | > |
| | | </slot> |
| | | </div> |
| | | </div> |
| | |
| | | import TaskPrice from './TaskPrice.vue'; |
| | | import { CommonTaskCardProps } from './card'; |
| | | import dayjs from 'dayjs'; |
| | | import { TaskUtils } from '@12333/utils'; |
| | | import { TaskUtils, toThousand } from '@12333/utils'; |
| | | |
| | | defineOptions({ |
| | | name: 'TaskCard', |
| | |
| | | /** 服务费 */ |
| | | serviceFee?: number; |
| | | settlementCycle?: EnumSettlementCycle; |
| | | /** 福利 */ |
| | | benefits?: API.GetTaskInfoQueryResultBenefit[]; |
| | | genderLimit?: EnumUserGender; |
| | | /** 资格证书类型 */ |
| | | credentialLimits?: API.GetTaskInfoQueryResultCredentialLimit[]; |
| | | /** 任务地点所属省份编号 */ |
| | | provinceCode?: string; |
| | | /** 任务地点所属省份 */ |
| | | provinceContent?: string; |
| | | /** 任务地点所属城市编号 */ |
| | | cityCode?: string; |
| | | /** 任务地点所属城市 */ |
| | | cityContent?: string; |
| | | /** 任务地点名称 */ |
| | | addressName?: string; |
| | | /** 任务地点详细地址 */ |
| | | addressDetail?: string; |
| | | /** 经度 */ |
| | | longitude?: number; |
| | | /** 纬度 */ |
| | | latitude?: number; |
| | | /** 报名人数 */ |
| | | userCount?: number; |
| | | status?: EnumTaskStatus; |
| | |
| | | showActions: true, |
| | | }); |
| | | |
| | | function handleSign() {} |
| | | const emit = defineEmits<{ |
| | | (e: 'apply', id: string): void; |
| | | }>(); |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | |
| | | }); |
| | | |
| | | type Props = { |
| | | value?: number; |
| | | value?: number | string; |
| | | unit?: string; |
| | | }; |
| | | |
| | |
| | | createdTime?: string; |
| | | /** 是否已收藏 */ |
| | | isCollected?: boolean; |
| | | status?: EnumTaskStatus; |
| | | releaseStatus?: EnumTaskReleaseStatus; |
| | | } |
| | | |
| | | interface GetTaskInfoQueryResultBenefit { |
| | |
| | | |
| | | static currentProvinceName: string; |
| | | |
| | | static blackList = ['江西省']; |
| | | static blackList = []; |
| | | |
| | | static async getLocation() { |
| | | if (!this.wxLocation) { |
| | |
| | | static getLocationByIp() { |
| | | return axios |
| | | .get<LocationResponse>( |
| | | `https://apis.map.qq.com/ws/location/v1/ip?key=HH7BZ-5L2KI-TN3GW-U5HKU-MK5H3-VOBZH` |
| | | `https://apis.map.qq.com/ws/location/v1/ip?key=HH7BZ-5L2KI-TN3GW-U5HKU-MK5H3-VOBZH`, |
| | | { |
| | | timeout: 3000, |
| | | } |
| | | ) |
| | | .then((res) => res.data); |
| | | } |