diff --git a/src/components/product-dialog/publish-job/index.tsx b/src/components/product-dialog/publish-job/index.tsx index 75314a8..f12bb0a 100644 --- a/src/components/product-dialog/publish-job/index.tsx +++ b/src/components/product-dialog/publish-job/index.tsx @@ -99,12 +99,8 @@ export function CompanyPublishJobDialog(props: IProps) { const handleNext = useCallback(async () => { onClose(true); - if (userInfo.bossAuthStatus) { - navigateTo(PageUrl.JobPublish); - } else { - navigateTo(PageUrl.CertificationStart); - } - }, [userInfo, onClose]); + navigateTo(PageUrl.JobPublish); + }, [onClose]); useEffect(() => { initRef.current = async () => { diff --git a/src/components/product-dialog/steps-ui/company-publish-job-buy.tsx b/src/components/product-dialog/steps-ui/company-publish-job-buy.tsx index 2d538b2..1570a8c 100644 --- a/src/components/product-dialog/steps-ui/company-publish-job-buy.tsx +++ b/src/components/product-dialog/steps-ui/company-publish-job-buy.tsx @@ -16,6 +16,7 @@ import { postSubscribe, subscribeMessage } from '@/utils/subscribe'; import Toast from '@/utils/toast'; interface IProps { + defaultSelect?: number; onNext: () => void; } @@ -85,8 +86,8 @@ const subscribe = async () => { }; export default function CompanyPublishJobBuy(props: IProps) { - const { onNext } = props; - const [selectItem, setSelectItem] = useState(LIST[0]); + const { onNext, defaultSelect = 0 } = props; + const [selectItem, setSelectItem] = useState(LIST[defaultSelect]); const handleClickItem = useCallback((newSelectItem: Item) => setSelectItem(newSelectItem), []); diff --git a/src/hooks/use-cached-job.tsx b/src/hooks/use-cached-job.tsx new file mode 100644 index 0000000..1064c7e --- /dev/null +++ b/src/hooks/use-cached-job.tsx @@ -0,0 +1,10 @@ +import { useSelector } from 'react-redux'; + +import { selectCreatedJob } from '@/store/selector/job'; + +function useCachedJob() { + const data = useSelector(selectCreatedJob); + return data; +} + +export default useCachedJob; diff --git a/src/http/api.ts b/src/http/api.ts index d4f3046..6a59d63 100644 --- a/src/http/api.ts +++ b/src/http/api.ts @@ -1,5 +1,5 @@ // export const DOMAIN = 'http://192.168.60.148:8082'; -export const DOMAIN = 'https://neighbourhood.cn'; +export const DOMAIN = 'https://dev.neighbourhood.cn'; export const BASE_URL = `${DOMAIN}/api`; export enum API { diff --git a/src/pages/anchor/index.tsx b/src/pages/anchor/index.tsx index 0ee94c7..294d1ed 100644 --- a/src/pages/anchor/index.tsx +++ b/src/pages/anchor/index.tsx @@ -174,7 +174,7 @@ export default function AnchorPage() { try { const { jobResults = [] } = await requestJobManageList({ status: JobManageStatus.Open }); if (!jobResults.length) { - Toast.info('当前是根据定位为您展示主播'); + // Toast.info('当前是根据定位为您展示主播'); return; } const lastSelectJobId = getLastSelectMyJobId(); diff --git a/src/pages/certification-manage/index.tsx b/src/pages/certification-manage/index.tsx index cb382cc..b19df1d 100644 --- a/src/pages/certification-manage/index.tsx +++ b/src/pages/certification-manage/index.tsx @@ -6,14 +6,15 @@ import classNames from 'classnames'; import { useCallback, useEffect, useState } from 'react'; import JobManageList, { IJobManageListProps } from '@/components/job-manage-list'; -import { CompanyPublishJobDialog } from '@/components/product-dialog/publish-job'; import SafeBottomPadding from '@/components/safe-bottom-padding'; +import { PageUrl } from '@/constants/app'; import { ReportEventId } from '@/constants/event'; import { JOB_MANAGE_TABS, JobManageStatus, JobManageType } from '@/constants/job'; import useListHeight, { IUseListHeightProps } from '@/hooks/use-list-height'; import useUserInfo from '@/hooks/use-user-info'; import { logWithPrefix } from '@/utils/common'; import { reportEvent } from '@/utils/event'; +import { navigateTo } from '@/utils/route'; import { ensureUserInfo } from '@/utils/user'; import './index.less'; @@ -91,7 +92,6 @@ export default function CertificationManage() { const userInfo = useUserInfo(); const listHeight = useListHeight(CALC_LIST_PROPS); const [tabType, setTabType] = useState(JobManageType.All); - const [showPublish, setShowPublish] = useState(false); const handleTypeChange = useCallback(value => setTabType(value), []); @@ -101,7 +101,7 @@ export default function CertificationManage() { if (!(await ensureUserInfo(userInfo))) { return; } - setShowPublish(true); + navigateTo(PageUrl.JobPublish); }, [userInfo]); return ( @@ -124,7 +124,6 @@ export default function CertificationManage() { -
{showPublish && setShowPublish(false)} />}
); } diff --git a/src/pages/certification/index.tsx b/src/pages/certification/index.tsx index 876a617..463d998 100644 --- a/src/pages/certification/index.tsx +++ b/src/pages/certification/index.tsx @@ -7,7 +7,7 @@ import BlFormInput from '@/components/bl-form-input'; import BlFormItem from '@/components/bl-form-item'; import LoadingDialog from '@/components/loading-dialog'; import SafeBottomPadding from '@/components/safe-bottom-padding'; -import { PageUrl } from '@/constants/app'; +import { EventName, PageUrl } from '@/constants/app'; import { CertificationStatusType } from '@/constants/company'; import { CollectEventName, ReportEventId } from '@/constants/event'; import useUserInfo from '@/hooks/use-user-info'; @@ -16,12 +16,18 @@ import { isValidIdCard, isValidPhone, logWithPrefix } from '@/utils/common'; import { postCertification, getPhone } from '@/utils/company'; import { collectEvent, reportEvent } from '@/utils/event'; import { chooseMedia } from '@/utils/material'; -import { redirectTo } from '@/utils/route'; +import { navigateBack, redirectTo } from '@/utils/route'; import Toast from '@/utils/toast'; import { dispatchUpdateUser, requestUserInfo } from '@/utils/user'; import { uploadVideo } from '@/utils/video'; import './index.less'; +import { requestProductBalance } from '@/utils/product'; +import { ProductType } from '@/constants/product'; +import useCachedJob from '@/hooks/use-cached-job'; +import { postCreateJob } from '@/utils/job'; +import { Dialog } from '@taroify/core'; +import CompanyPublishJobBuy from '@/components/product-dialog/steps-ui/company-publish-job-buy'; const PREFIX = 'page-certification'; const log = logWithPrefix(PREFIX); @@ -100,6 +106,8 @@ export default function Certification() { // const [code, setCode] = useState(''); const [company, setCompany] = useState(''); const [open, setOpen] = useState(false); + const [showBuy, setShowBuy] = useState(false); + const cachedJobData = useCachedJob(); const handleClickIdCardLeft = useCallback(async () => { reportEvent(ReportEventId.CLICK_UPLOAD_ID_CARD, { type: 'left' }); @@ -133,6 +141,25 @@ export default function Certification() { setCompany(value); }, []); + const handleCreateJob = useCallback(async () => { + if (cachedJobData.employType) { + Taro.showLoading(); + try { + await postCreateJob(cachedJobData); + Taro.eventCenter.trigger(EventName.COMPANY_JOB_PUBLISH_CHANGED); + await Toast.success('通告创建成功', 1500, true); + } catch (e) { + console.error('submit error', e); + Toast.error('通告审核失败请重试'); + collectEvent(CollectEventName.PUBLISH_JOB_FAILED, e); + } finally { + Taro.hideLoading(); + } + } else { + Toast.error('数据出错'); + } + }, [cachedJobData]); + const handleSubmit = useCallback(async () => { reportEvent(ReportEventId.CLICK_CERTIFICATION_SUBMIT); const data: ICertificationRequest = { @@ -157,6 +184,17 @@ export default function Certification() { return; } dispatchUpdateUser({ bossAuthStatus: CertificationStatusType.Success }); + // 判断付钱没有 + const [time] = await requestProductBalance(ProductType.CompanyPublishJob); + if (time <= 0) { + // 付钱 + setShowBuy(true); + Taro.hideLoading(); + return; + } else { + // 获取data创建 + await handleCreateJob(); + } redirectTo(PageUrl.CertificationManage); } catch (e) { console.error('submit error', e); @@ -262,6 +300,11 @@ export default function Certification() {
+ setShowBuy(false)}> + + + + ); } diff --git a/src/pages/job-publish/index.tsx b/src/pages/job-publish/index.tsx index 119e5d4..c31d480 100644 --- a/src/pages/job-publish/index.tsx +++ b/src/pages/job-publish/index.tsx @@ -1,6 +1,7 @@ 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, useState } from 'react'; @@ -12,15 +13,29 @@ 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 { cacheCreateJob } 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 } from '@/utils/job'; +import { + postCloseJob, + postCreateJob, + postUpdateJob, + requestJobDetail, + isFullTimePriceRequired, + isPartTimePriceRequired, +} 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'; @@ -91,6 +106,8 @@ export default function JobPublish() { const [city, setCity] = useState(); const [showCityPicker, setShowCityPicker] = useState(false); const [address, setAddress] = useState(''); + const [showBuy, setShowBuy] = useState(false); + const userInfo = useUserInfo(); const handleEmployTypeChange = useCallback((value: EmployType) => { setEmployType(value); @@ -144,7 +161,7 @@ export default function JobPublish() { } }, [job]); - const handleSubmit = useCallback(async () => { + const getCreateJobInfo = useCallback((): [CreateJobInfo, string[]] => { const cityCodes = city || []; const data: CreateJobInfo = { title, @@ -160,6 +177,11 @@ export default function JobPublish() { 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); @@ -178,6 +200,20 @@ export default function JobPublish() { await postUpdateJob(data); Taro.eventCenter.trigger(EventName.JOB_UPDATE, job!.id); } else { + if (userInfo.bossAuthStatus !== CertificationStatusType.Success) { + // 去认证 + store.dispatch(cacheCreateJob(data)); + navigateTo(PageUrl.CertificationStart); + Taro.hideLoading(); + return; + } + const [time] = await requestProductBalance(ProductType.CompanyPublishJob); + if (time <= 0) { + // 付钱 + setShowBuy(true); + Taro.hideLoading(); + return; + } await postCreateJob(data); } Taro.eventCenter.trigger(EventName.COMPANY_JOB_PUBLISH_CHANGED); @@ -190,7 +226,30 @@ export default function JobPublish() { } finally { Taro.hideLoading(); } - }, [isUpdate, job, title, employType, category, describe, city, salary, address]); + }, [getCreateJobInfo, isUpdate, job, userInfo.bossAuthStatus]); + + const handleNext = useCallback(async () => { + const [data, cityCodes] = getCreateJobInfo(); + + const cityValues = getCityValues(cityCodes); + if (!data.address.startsWith(cityValues)) { + data.address = `${cityValues}${data.address}`; + } + Taro.showLoading(); + + try { + await postCreateJob(data); + Taro.eventCenter.trigger(EventName.COMPANY_JOB_PUBLISH_CHANGED); + await Toast.success('创建成功', 1500, true); + navigateBack(); + } catch (e) { + console.error('submit error', e); + Toast.error('审核失败请重试'); + collectEvent(CollectEventName.PUBLISH_JOB_FAILED, e); + } finally { + Taro.hideLoading(); + } + }, [getCreateJobInfo]); useEffect(() => { const callback = (d: string) => setDescribe(d); @@ -306,6 +365,11 @@ export default function JobPublish() { onConfirm={handleConfirmCityPicker} onCancel={() => setShowCityPicker(false)} /> + setShowBuy(false)}> + + + + ); diff --git a/src/store/actions/index.ts b/src/store/actions/index.ts index 7d28390..5358f5a 100644 --- a/src/store/actions/index.ts +++ b/src/store/actions/index.ts @@ -1,3 +1,4 @@ export * from './app'; export * from './user'; export * from './message'; +export * from './job'; diff --git a/src/store/actions/job.ts b/src/store/actions/job.ts new file mode 100644 index 0000000..9e0adef --- /dev/null +++ b/src/store/actions/job.ts @@ -0,0 +1,7 @@ +import { CreateJobInfo } from '@/types/job'; + +import { CREATE_JOB } from '../constants'; + +export const cacheCreateJob = (value: CreateJobInfo) => ({ type: CREATE_JOB, value }); + +export const clearCachedJob = () => ({ type: CREATE_JOB, value: {} }); diff --git a/src/store/constants.ts b/src/store/constants.ts index 02411e3..1effc9d 100644 --- a/src/store/constants.ts +++ b/src/store/constants.ts @@ -5,3 +5,4 @@ export const SET_USER_INFO = 'SET_USER_INFO'; export const SET_BIND_PHONE = 'SET_BIND_PHONE'; export const SET_USER_MESSAGE = 'SET_USER_MESSAGE'; export const SET_INVITE_CODE = 'SET_INVITE_CODE'; +export const CREATE_JOB = 'CREATE_JOB'; diff --git a/src/store/reducers/index.ts b/src/store/reducers/index.ts index 82d0607..853436d 100644 --- a/src/store/reducers/index.ts +++ b/src/store/reducers/index.ts @@ -1,6 +1,7 @@ import { combineReducers } from 'redux'; import appState from './app'; +import jobState from './job'; import message from './message'; import partnerInfo from './partner'; import userInfo from './user'; @@ -10,4 +11,5 @@ export default combineReducers({ userInfo, message, partnerInfo, + jobState, }); diff --git a/src/store/reducers/job.ts b/src/store/reducers/job.ts new file mode 100644 index 0000000..9b16fee --- /dev/null +++ b/src/store/reducers/job.ts @@ -0,0 +1,19 @@ +import { Action } from 'redux'; + +import { CreateJobInfo } from '@/types/job'; + +import { CREATE_JOB } from '../constants'; + +const INIT_STATE: Partial = {}; + +const userInfo = (state: Partial = INIT_STATE, action: Action): Partial => { + const { type, value } = action as BL.Anything; + switch (type) { + case CREATE_JOB: + return value; + default: + return state; + } +}; + +export default userInfo; diff --git a/src/store/selector/job.ts b/src/store/selector/job.ts new file mode 100644 index 0000000..8810fb4 --- /dev/null +++ b/src/store/selector/job.ts @@ -0,0 +1,3 @@ +import { IState } from '@/types/store'; + +export const selectCreatedJob = (state: IState) => state.jobState; diff --git a/src/types/store.ts b/src/types/store.ts index 2ee95ae..5890834 100644 --- a/src/types/store.ts +++ b/src/types/store.ts @@ -1,4 +1,5 @@ import { RoleType, PageType } from '@/constants/app'; +import { CreateJobInfo } from '@/types/job'; import { UserMessage } from '@/types/message'; import { PartnerInfo } from '@/types/partner'; @@ -10,6 +11,7 @@ export interface IState { userInfo: UserInfo; message: UserMessage; partnerInfo: PartnerInfo; + jobState: CreateJobInfo; } export interface AppState {