import { BaseEventOrig, Button, InputProps } from '@tarojs/components'; import Taro, { useLoad } from '@tarojs/taro'; import { Dialog } from '@taroify/core'; import classNames from 'classnames'; import { useCallback, useEffect, useRef, useState } from 'react'; import BlFormCell from '@/components/bl-form-cell'; import BlFormInput from '@/components/bl-form-input'; import BlFormItem from '@/components/bl-form-item'; import { BlFormRadio, BlFormRadioGroup } from '@/components/bl-form-radio'; import BlFormSelect from '@/components/bl-form-select'; import BlSalaryInput, { BlSalaryValue } from '@/components/bl-salary-input'; import { CityPickerPopup } from '@/components/city-picker'; import PageLoading from '@/components/page-loading'; import CompanyPublishJobBuy from '@/components/product-dialog/steps-ui/company-publish-job-buy'; import SafeBottomPadding from '@/components/safe-bottom-padding'; import { EventName, PageUrl } from '@/constants/app'; import { CertificationStatusType } from '@/constants/company'; import { CollectEventName } from '@/constants/event'; import { EMPLOY_TYPE_TITLE_MAP, EmployType, JOB_TYPE_SELECT_OPTIONS, JobType } from '@/constants/job'; import { ProductType } from '@/constants/product'; import useUserInfo from '@/hooks/use-user-info'; import store from '@/store'; import { cacheJobId } from '@/store/actions'; import { CreateJobInfo, JobDetails } from '@/types/job'; import { logWithPrefix } from '@/utils/common'; import { collectEvent } from '@/utils/event'; import { postCloseJob, postCreateJob, postUpdateJob, requestJobDetail, isFullTimePriceRequired, isPartTimePriceRequired, postPublishJob, } from '@/utils/job'; import { getCityValues } from '@/utils/location'; import { requestProductBalance } from '@/utils/product'; import { getPageQuery, navigateBack, navigateTo } from '@/utils/route'; import Toast from '@/utils/toast'; import './index.less'; const PREFIX = 'page-job-publish'; const log = logWithPrefix(PREFIX); const isInvalidCreateJobInfo = (data: CreateJobInfo) => { const { title, category, employType, provinceCode, cityCode, countyCode, address, jobDescription, lowPriceForFullTime, highPriceForFullTime, lowPriceForPartyTime, highPriceForPartyTime, } = data; if (!category) { return '请选择通告品类'; } if (!title) { return '请选择通告标题'; } if (!jobDescription) { return '请输入通告描述'; } if (isFullTimePriceRequired(employType)) { if (!lowPriceForFullTime || !highPriceForFullTime) { return '薪资范围不能为空'; } if (lowPriceForFullTime > highPriceForFullTime) { return '薪资最高值不能低于最低值'; } } if (isPartTimePriceRequired(employType)) { if (!lowPriceForPartyTime || !highPriceForPartyTime) { return '薪资范围不能为空'; } if (lowPriceForPartyTime > highPriceForPartyTime) { return '薪资最高值不能低于最低值'; } } if (!provinceCode || !cityCode || !countyCode) { return '请输入工作地址'; } if (!address) { return '请输入详细地址'; } }; export default function JobPublish() { const [loading, setLoading] = useState(false); const [isUpdate, setIsUpdate] = useState(false); const [job, setJob] = useState(null); const [reason, setReason] = useState(''); const [employType, setEmployType] = useState(EmployType.Full); const [category, setCategory] = useState(JobType.Finery); const [title, setTitle] = useState(''); const [describe, setDescribe] = useState(''); const [salary, setSalary] = useState(['', '', '', ''] as unknown as BlSalaryValue); const [city, setCity] = useState(); const [showCityPicker, setShowCityPicker] = useState(false); const [address, setAddress] = useState(''); const [showBuy, setShowBuy] = useState(false); const createdJobIdRef = useRef(''); const userInfo = useUserInfo(); const handleEmployTypeChange = useCallback((value: EmployType) => { setEmployType(value); }, []); const handleSelectCategory = useCallback((value: JobType) => { setCategory(value); }, []); const handleInputTitle = useCallback((e: BaseEventOrig) => { const value = e.detail.value || ''; setTitle(value); }, []); const handleClickEditDescribe = useCallback(() => navigateTo(PageUrl.JobPublishDescribe, { describe }), [describe]); const handleSalaryChange = useCallback((value: BlSalaryValue) => { setSalary(value); }, []); const handleClickCity = useCallback(() => setShowCityPicker(true), []); const handleConfirmCityPicker = useCallback((areaValues: string[]) => { log('handleConfirmCityPicker', areaValues); setShowCityPicker(false); setCity(areaValues); setAddress(''); }, []); const handleInputAddress = useCallback((e: BaseEventOrig) => { const value = e.detail.value || ''; setAddress(value); }, []); const refreshJobPublishList = useCallback(() => { Taro.eventCenter.trigger(EventName.COMPANY_JOB_PUBLISH_CHANGED); setTimeout(() => { Taro.eventCenter.trigger(EventName.COMPANY_JOB_PUBLISH_CHANGED); }, 300); }, []); const handleClose = useCallback(async () => { if (!job) { Toast.error('数据出错请重试'); return; } try { Taro.showLoading(); await postCloseJob(job.id); refreshJobPublishList(); navigateBack(); } catch (e) { console.error('submit error', e); Toast.error('关闭失败请重试'); collectEvent(CollectEventName.CLOSE_JOB_FAILED, e); } finally { Taro.hideLoading(); } }, [job, refreshJobPublishList]); const getCreateJobInfo = useCallback((): [CreateJobInfo, string[]] => { const cityCodes = city || []; const data: CreateJobInfo = { title, employType, category: category!, jobDescription: describe, provinceCode: cityCodes[0], cityCode: cityCodes[1], countyCode: cityCodes[2], lowPriceForFullTime: !isFullTimePriceRequired(employType) ? 0 : salary[0] * 1000, highPriceForFullTime: !isFullTimePriceRequired(employType) ? 0 : salary[1] * 1000, lowPriceForPartyTime: !isPartTimePriceRequired(employType) ? 0 : salary[2], highPriceForPartyTime: !isPartTimePriceRequired(employType) ? 0 : salary[3], address: address, }; return [data, cityCodes]; }, [address, category, city, describe, employType, salary, title]); const handleSubmit = useCallback(async () => { const [data, cityCodes] = getCreateJobInfo(); const errMsg = isInvalidCreateJobInfo(data); if (errMsg) { Toast.info(errMsg); return; } try { Taro.showLoading(); // 将省市区拼到最前面 const cityValues = getCityValues(cityCodes); if (!data.address.startsWith(cityValues)) { data.address = `${cityValues}${data.address}`; } const isUpdateJob = isUpdate && job; if (isUpdateJob) { data.jobId = job!.id; await postUpdateJob(data); Taro.eventCenter.trigger(EventName.JOB_UPDATE, job!.id); } else { const jobId = await postCreateJob(data); createdJobIdRef.current = jobId; refreshJobPublishList(); if (userInfo.bossAuthStatus !== CertificationStatusType.Success) { // 去认证 store.dispatch(cacheJobId(jobId)); navigateTo(PageUrl.CertificationStart); Taro.hideLoading(); return; } const [time] = await requestProductBalance(ProductType.CompanyPublishJob); if (time <= 0) { // 付钱 setShowBuy(true); Taro.hideLoading(); return; } await postPublishJob(jobId); } refreshJobPublishList(); await Toast.success(isUpdateJob ? '更新成功' : '创建并发布成功', 1500, true); navigateBack(); } catch (e) { createdJobIdRef.current = ''; console.error('submit error', e); Toast.error('审核失败请重试'); collectEvent(CollectEventName.PUBLISH_JOB_FAILED, e); } finally { Taro.hideLoading(); } }, [getCreateJobInfo, isUpdate, job, userInfo.bossAuthStatus, refreshJobPublishList]); const handleNext = useCallback(async () => { Taro.showLoading(); try { await postPublishJob(createdJobIdRef.current); refreshJobPublishList(); await Toast.success('发布成功', 1500, true); navigateBack(); } catch (e) { console.error('submit error', e); Toast.error('审核失败请重试'); collectEvent(CollectEventName.PUBLISH_JOB_FAILED, e); } finally { Taro.hideLoading(); } }, [refreshJobPublishList]); const handleClosePublishJob = useCallback(() => { setShowBuy(false); navigateBack(-1); }, []); useEffect(() => { const callback = (d: string) => setDescribe(d); Taro.eventCenter.on(EventName.EDIT_JOB_DESCRIBE, callback); return () => { Taro.eventCenter.off(EventName.EDIT_JOB_DESCRIBE, callback); }; }, []); useLoad(async () => { const query = getPageQuery<{ jobId: string }>(); const jobId = query?.jobId; if (!jobId) { return; } try { setLoading(true); setIsUpdate(true); const details = await requestJobDetail(jobId); setJob(details); details.title && setTitle(details.title); details.employType && setEmployType(details.employType); details.category && setCategory(details.category); details.jobDescription && setDescribe(details.jobDescription); details.jobLocation.provinceCode && details.jobLocation.cityCode && details.jobLocation.countyCode && setCity([details.jobLocation.provinceCode, details.jobLocation.cityCode, details.jobLocation.countyCode]); details.lowPriceForFullTime && details.highPriceForFullTime && details.lowPriceForPartyTime && details.highPriceForPartyTime && setSalary([ details.lowPriceForFullTime / 1000, details.highPriceForFullTime / 1000, details.lowPriceForPartyTime, details.highPriceForPartyTime, ]); details.jobLocation.address && setAddress(details.jobLocation.address); details.verifyFailReason && setReason(details.verifyFailReason); } catch (e) { console.error(e); Toast.error('出错了,请重试'); } finally { setLoading(false); } }); if (loading) { return ; } return (
{reason &&
{reason}
}
注:通告标题和工作城市发布后不可修改
{!isUpdate && ( )} {isUpdate && ( <> )}
setShowCityPicker(false)} />
); }