import { Button } from '@tarojs/components'; import Taro from '@tarojs/taro'; import { Fragment, useCallback, useEffect, useRef, useState } from 'react'; import SafeBottomPadding from '@/components/safe-bottom-padding'; import { EventName } from '@/constants/app'; import { CollectEventName } from '@/constants/event'; import { ProfileGroupType, ProfileTitleMap } from '@/constants/material'; import ProfileAdvantagesFragment from '@/fragments/profile/advantages'; import ProfileBasicFragment from '@/fragments/profile/basic'; import ProfileExperienceFragment from '@/fragments/profile/experience'; import ProfileIntentionFragment from '@/fragments/profile/intention'; import useLocation from '@/hooks/use-location'; import { MaterialProfile } from '@/types/material'; import { logWithPrefix } from '@/utils/common'; import { collectEvent } from '@/utils/event'; import { isFullTimePriceRequired, isPartTimePriceRequired } from '@/utils/job'; import { updateProfile, subscribeMaterialMessage } from '@/utils/material'; import { navigateBack } from '@/utils/route'; import Toast from '@/utils/toast'; import './index.less'; import ProfileOthersFragment from '@/fragments/profile/others'; const PREFIX = 'page-material-create-profile'; const log = logWithPrefix(PREFIX); const REQUIRE_KEYS = { [ProfileGroupType.Basic]: ['name', 'gender', 'age'], [ProfileGroupType.Intention]: [ 'cityCodes', 'employType', 'fullTimeMinPrice', 'fullTimeMaxPrice', 'partyTimeMinPrice', 'partyTimeMaxPrice', ], [ProfileGroupType.Experience]: [], [ProfileGroupType.Advantages]: [], [ProfileGroupType.Others]: [], }; const COULD_SKIP = [ProfileGroupType.Experience, ProfileGroupType.Others]; const CONDITIONAL_REQUIRED_KEYS = { [ProfileGroupType.Intention]: [ ['fullTimeMinPrice', data => isFullTimePriceRequired(data.employType)], ['fullTimeMaxPrice', data => isFullTimePriceRequired(data.employType)], ['partyTimeMinPrice', data => isPartTimePriceRequired(data.employType)], ['partyTimeMaxPrice', data => isPartTimePriceRequired(data.employType)], ], }; const getNextStepGroupType = (curType: ProfileGroupType) => { switch (curType) { case ProfileGroupType.Basic: return ProfileGroupType.Experience; case ProfileGroupType.Intention: return ProfileGroupType.Basic; case ProfileGroupType.Experience: return ProfileGroupType.Others; case ProfileGroupType.Others: return ProfileGroupType.Advantages; default: return null; } }; const isValidFormData = (type: ProfileGroupType, data: Partial) => { const requireKeys = REQUIRE_KEYS[type] || []; const conditionalKeys = CONDITIONAL_REQUIRED_KEYS[type] || []; const requiredValidator = (key: any) => typeof data[key] !== 'undefined' && data[key] !== ''; return ( requireKeys.every(requiredValidator) && conditionalKeys.every(([key, validator]) => { return !validator(data) || requiredValidator(key); }) ); }; export default function MaterialCreateProfile() { const location = useLocation(); const [groupType, setGroupType] = useState(ProfileGroupType.Intention); const ref = useRef<{ getData: () => Partial } | null>(null); const ProfileFragment = groupType === ProfileGroupType.Basic ? ProfileBasicFragment : groupType === ProfileGroupType.Intention ? ProfileIntentionFragment : groupType === ProfileGroupType.Experience ? ProfileExperienceFragment : groupType === ProfileGroupType.Advantages ? ProfileAdvantagesFragment : groupType === ProfileGroupType.Others ? ProfileOthersFragment : Fragment; const handleSkip = useCallback(() => { const nextType = getNextStepGroupType(groupType); if (nextType) { setGroupType(nextType); } }, [groupType]); const handleSubmit = useCallback(async () => { try { const data = ref.current?.getData(); log('handleSubmit data:', data); if (!data) { throw new Error('数据异常'); } if (!isValidFormData(groupType, data)) { Toast.error('重要选项必填!'); return; } const nextType = getNextStepGroupType(groupType); log('handleSubmit nextType:', nextType); if (nextType) { await updateProfile(data); } else { // 发起订阅不能在异步任务中,保证是第一个 await Promise.all([subscribeMaterialMessage(), updateProfile(data)]); } Taro.eventCenter.trigger(EventName.CREATE_PROFILE); nextType ? setGroupType(nextType) : navigateBack(2); } catch (e) { Toast.error('保存失败请重试'); collectEvent(CollectEventName.CREATE_MATERIAL_FAILED, e); } }, [ref, groupType]); useEffect(() => { const title = ProfileTitleMap[groupType]; Taro.setNavigationBarTitle({ title }); }, [groupType]); const couldSkip = COULD_SKIP.includes(groupType); return (
{couldSkip && (
跳过
)}
); }