featL
This commit is contained in:
@ -1,106 +0,0 @@
|
|||||||
import Taro from '@tarojs/taro';
|
|
||||||
|
|
||||||
import { Dialog } from '@taroify/core';
|
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
||||||
|
|
||||||
import { DialogStatus, PREFIX } from '@/components/product-dialog/const';
|
|
||||||
import ContactCustomerService from '@/components/product-dialog/steps-ui/job-contact-customer';
|
|
||||||
import ContactDirect from '@/components/product-dialog/steps-ui/job-contact-direct';
|
|
||||||
import UnableUnlockContent from '@/components/product-dialog/steps-ui/job-unable';
|
|
||||||
import { EventName } from '@/constants/app';
|
|
||||||
import { DeclarationType, ProductType } from '@/constants/product';
|
|
||||||
import { JobDetails } from '@/types/job';
|
|
||||||
import { GetProductIsUnlockResponse, ProductInfo } from '@/types/product';
|
|
||||||
import { logWithPrefix } from '@/utils/common';
|
|
||||||
import { requestUseProduct } from '@/utils/product';
|
|
||||||
import Toast from '@/utils/toast';
|
|
||||||
|
|
||||||
import '../index.less';
|
|
||||||
|
|
||||||
interface IProps {
|
|
||||||
data: JobDetails;
|
|
||||||
productRecord?: GetProductIsUnlockResponse;
|
|
||||||
productInfo?: ProductInfo;
|
|
||||||
onClose: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PRODUCT_CODE = ProductType.VIP;
|
|
||||||
const log = logWithPrefix('product-contact-dialog');
|
|
||||||
|
|
||||||
function ProductContactDialog(props: Omit<IProps, 'visible'>) {
|
|
||||||
const { data, productInfo: productInfoProps, productRecord, onClose } = props;
|
|
||||||
const [status, setStatus] = useState<DialogStatus>(DialogStatus.LOADING);
|
|
||||||
const [publisherAcctNo, setPublisherAcctNo] = useState<string>('');
|
|
||||||
const initRef = useRef(() => {});
|
|
||||||
|
|
||||||
const handleCloseDialog = useCallback(() => {
|
|
||||||
onClose();
|
|
||||||
}, [onClose]);
|
|
||||||
|
|
||||||
const handleReport = useCallback(() => {
|
|
||||||
log('report', data.id);
|
|
||||||
}, [data]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
initRef.current = async () => {
|
|
||||||
const handleContact = (declarationTypeResult?: ProductInfo['declarationTypeResult']) => {
|
|
||||||
if (declarationTypeResult?.type === DeclarationType.Direct && declarationTypeResult.publisherAcctNo) {
|
|
||||||
console.log('set JOB_CONTACT_DIRECT', declarationTypeResult.publisherAcctNo)
|
|
||||||
setStatus(DialogStatus.JOB_CONTACT_DIRECT);
|
|
||||||
setPublisherAcctNo(declarationTypeResult.publisherAcctNo);
|
|
||||||
} else {
|
|
||||||
console.log('set JOB_CONTACT_CS')
|
|
||||||
setStatus(DialogStatus.JOB_CONTACT_CS);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
Taro.showLoading();
|
|
||||||
// if (1 < 2) {
|
|
||||||
// setStatus(DialogStatus.JOB_CONTACT_CS);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
log('requestProductUseRecord result', productRecord);
|
|
||||||
if (productRecord) {
|
|
||||||
handleContact(productRecord.declarationTypeResult);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!productInfoProps?.balance) {
|
|
||||||
setStatus(DialogStatus.JOB_UNABLE_UNLOCK);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const productInfo = await requestUseProduct(PRODUCT_CODE, { jobId: data.id });
|
|
||||||
Taro.eventCenter.trigger(EventName.READ_CONTACT);
|
|
||||||
console.log('开始报单', productInfo);
|
|
||||||
handleContact(productInfo ? productInfo.declarationTypeResult : undefined);
|
|
||||||
} catch (e) {
|
|
||||||
Toast.error('出错了,请重试');
|
|
||||||
console.log(e);
|
|
||||||
handleCloseDialog();
|
|
||||||
} finally {
|
|
||||||
Taro.hideLoading();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [data, handleCloseDialog, productRecord, productInfoProps?.balance]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
initRef.current();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (status === DialogStatus.LOADING) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dialog className={PREFIX} onClose={onClose} open>
|
|
||||||
<Dialog.Content>
|
|
||||||
{status === DialogStatus.JOB_CONTACT_CS && <ContactCustomerService onAfterConfirm={handleCloseDialog} />}
|
|
||||||
{status === DialogStatus.JOB_CONTACT_DIRECT && (
|
|
||||||
<ContactDirect publisherAcctNo={publisherAcctNo} onAfterConfirm={handleCloseDialog} onReport={handleReport} />
|
|
||||||
)}
|
|
||||||
{status === DialogStatus.JOB_UNABLE_UNLOCK && <UnableUnlockContent onConfirm={handleCloseDialog} />}
|
|
||||||
</Dialog.Content>
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ProductContactDialog;
|
|
||||||
175
src/components/product-dialog/job-contact/index.tsx
Normal file
175
src/components/product-dialog/job-contact/index.tsx
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
import Taro from '@tarojs/taro';
|
||||||
|
|
||||||
|
import { Dialog } from '@taroify/core';
|
||||||
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import { DialogStatus, PREFIX } from '@/components/product-dialog/const';
|
||||||
|
import JobBuy from '@/components/product-dialog/steps-ui/job-buy';
|
||||||
|
import ContactCustomerService from '@/components/product-dialog/steps-ui/job-contact-customer';
|
||||||
|
import ContactDirect from '@/components/product-dialog/steps-ui/job-contact-direct';
|
||||||
|
import UnableUnlockContent from '@/components/product-dialog/steps-ui/job-unable';
|
||||||
|
import { DeclarationType, ProductType } from '@/constants/product';
|
||||||
|
import { JobDetails } from '@/types/job';
|
||||||
|
import { GetProductIsUnlockResponse, ProductInfo } from '@/types/product';
|
||||||
|
import { logWithPrefix } from '@/utils/common';
|
||||||
|
import { requestUseProduct } from '@/utils/product';
|
||||||
|
import Toast from '@/utils/toast';
|
||||||
|
|
||||||
|
import '../index.less';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
data: JobDetails;
|
||||||
|
/** Product use record from parent - if exists, user has already unlocked this job */
|
||||||
|
productRecord?: GetProductIsUnlockResponse | null;
|
||||||
|
/** Product balance info from parent */
|
||||||
|
productInfo?: ProductInfo;
|
||||||
|
/** Callback to refresh product balance in parent after purchase */
|
||||||
|
onRefreshBalance?: () => Promise<ProductInfo | undefined>;
|
||||||
|
onClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PRODUCT_CODE = ProductType.VIP;
|
||||||
|
const log = logWithPrefix('product-job-contact-dialog');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integrated dialog component for job contact flow
|
||||||
|
* Handles: balance check -> buy if needed -> use product -> show contact info
|
||||||
|
*
|
||||||
|
* @param productRecord - Pass from parent to avoid duplicate API calls
|
||||||
|
* @param productInfo - Pass from parent to avoid duplicate API calls
|
||||||
|
* @param onRefreshBalance - Callback to refresh balance in parent after purchase
|
||||||
|
*/
|
||||||
|
function ProductJobContactDialog(props: IProps) {
|
||||||
|
const { data, productRecord, productInfo, onRefreshBalance, onClose } = props;
|
||||||
|
const [status, setStatus] = useState<DialogStatus>(DialogStatus.LOADING);
|
||||||
|
const [publisherAcctNo, setPublisherAcctNo] = useState<string>('');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle contact display based on declaration type
|
||||||
|
*/
|
||||||
|
const showContactResult = useCallback((declarationTypeResult?: ProductInfo['declarationTypeResult']) => {
|
||||||
|
if (declarationTypeResult?.type === DeclarationType.Direct && declarationTypeResult.publisherAcctNo) {
|
||||||
|
log('show JOB_CONTACT_DIRECT', declarationTypeResult.publisherAcctNo);
|
||||||
|
setPublisherAcctNo(declarationTypeResult.publisherAcctNo);
|
||||||
|
setStatus(DialogStatus.JOB_CONTACT_DIRECT);
|
||||||
|
} else {
|
||||||
|
log('show JOB_CONTACT_CS');
|
||||||
|
setStatus(DialogStatus.JOB_CONTACT_CS);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use product and show contact info
|
||||||
|
*/
|
||||||
|
const consumeProductAndShowContact = useCallback(async () => {
|
||||||
|
const productResult = await requestUseProduct(PRODUCT_CODE, { jobId: data.id });
|
||||||
|
log('consumeProductAndShowContact result', productResult);
|
||||||
|
// Refresh balance in parent after consuming product
|
||||||
|
await onRefreshBalance?.();
|
||||||
|
showContactResult(productResult?.declarationTypeResult);
|
||||||
|
}, [data.id, showContactResult, onRefreshBalance]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback after successful purchase
|
||||||
|
* Refresh balance via parent callback and use product to show contact info
|
||||||
|
*/
|
||||||
|
const handleAfterBuy = useCallback(async () => {
|
||||||
|
log('handleAfterBuy - start');
|
||||||
|
try {
|
||||||
|
Taro.showLoading({ mask: true, title: '加载中...' });
|
||||||
|
|
||||||
|
// Refresh balance via parent callback
|
||||||
|
await onRefreshBalance?.();
|
||||||
|
|
||||||
|
// Use product and show contact info after purchase
|
||||||
|
await consumeProductAndShowContact();
|
||||||
|
} catch (e) {
|
||||||
|
log('handleAfterBuy error', e);
|
||||||
|
Toast.error('出错了,请重试');
|
||||||
|
onClose();
|
||||||
|
} finally {
|
||||||
|
Taro.hideLoading();
|
||||||
|
}
|
||||||
|
}, [consumeProductAndShowContact, onRefreshBalance, onClose]);
|
||||||
|
|
||||||
|
const handleReport = useCallback(() => {
|
||||||
|
log('report', data.id);
|
||||||
|
}, [data.id]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize dialog on mount
|
||||||
|
*/
|
||||||
|
useEffect(() => {
|
||||||
|
let isMounted = true;
|
||||||
|
|
||||||
|
const init = async () => {
|
||||||
|
try {
|
||||||
|
Taro.showLoading({ mask: true, title: '加载中...' });
|
||||||
|
|
||||||
|
log('init with productRecord', productRecord);
|
||||||
|
log('init with productInfo', productInfo);
|
||||||
|
|
||||||
|
// Step 1: Already unlocked - show contact directly
|
||||||
|
if (productRecord) {
|
||||||
|
log('show JOB_CONTACT_DIRECT from productRecord', productRecord.declarationTypeResult);
|
||||||
|
showContactResult(productRecord.declarationTypeResult);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2: No productInfo - error state
|
||||||
|
if (!productInfo) {
|
||||||
|
log('no productInfo provided, closing');
|
||||||
|
Toast.error('出错了,请重试');
|
||||||
|
onClose();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3: Determine status based on balance
|
||||||
|
if (!productInfo.isPaidVip && !productInfo.freeBalance) {
|
||||||
|
log('show JOB_BUY');
|
||||||
|
if (isMounted) setStatus(DialogStatus.JOB_BUY);
|
||||||
|
} else if (!productInfo.balance) {
|
||||||
|
log('show JOB_UNABLE_UNLOCK');
|
||||||
|
if (isMounted) setStatus(DialogStatus.JOB_UNABLE_UNLOCK);
|
||||||
|
} else {
|
||||||
|
await consumeProductAndShowContact();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
log('init error', e);
|
||||||
|
Toast.error('出错了,请重试');
|
||||||
|
onClose();
|
||||||
|
} finally {
|
||||||
|
Taro.hideLoading();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
init();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
isMounted = false;
|
||||||
|
};
|
||||||
|
// Only run on mount - props are captured at dialog open time
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (status === DialogStatus.LOADING) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog className={PREFIX} onClose={onClose} open>
|
||||||
|
<Dialog.Content>
|
||||||
|
{status === DialogStatus.JOB_CONTACT_CS && <ContactCustomerService onAfterConfirm={onClose} />}
|
||||||
|
{status === DialogStatus.JOB_CONTACT_DIRECT && (
|
||||||
|
<ContactDirect publisherAcctNo={publisherAcctNo} onAfterConfirm={onClose} onReport={handleReport} />
|
||||||
|
)}
|
||||||
|
{status === DialogStatus.JOB_BUY && (
|
||||||
|
<JobBuy onConfirm={handleAfterBuy} isCreateResume={productInfo?.isCreateResume} />
|
||||||
|
)}
|
||||||
|
{status === DialogStatus.JOB_UNABLE_UNLOCK && <UnableUnlockContent onConfirm={onClose} />}
|
||||||
|
</Dialog.Content>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProductJobContactDialog;
|
||||||
@ -12,9 +12,8 @@ import { JoinGroupHint } from '@/components/join-group-hint';
|
|||||||
import LoginButton from '@/components/login-button';
|
import LoginButton from '@/components/login-button';
|
||||||
import PageLoading from '@/components/page-loading';
|
import PageLoading from '@/components/page-loading';
|
||||||
import { PrejobPopup } from '@/components/prejob-popup';
|
import { PrejobPopup } from '@/components/prejob-popup';
|
||||||
import ProductContactDialog from '@/components/product-dialog/contact';
|
import ProductJobContactDialog from '@/components/product-dialog/job-contact';
|
||||||
import CompanyPublishJobBuy from '@/components/product-dialog/steps-ui/company-publish-job-buy';
|
import CompanyPublishJobBuy from '@/components/product-dialog/steps-ui/company-publish-job-buy';
|
||||||
import JobBuy from '@/components/product-dialog/steps-ui/job-buy';
|
|
||||||
import { EventName, PageUrl, RoleType } from '@/constants/app';
|
import { EventName, PageUrl, RoleType } from '@/constants/app';
|
||||||
import { CertificationStatusType } from '@/constants/company';
|
import { CertificationStatusType } from '@/constants/company';
|
||||||
import { ReportEventId } from '@/constants/event';
|
import { ReportEventId } from '@/constants/event';
|
||||||
@ -71,13 +70,13 @@ const getMapCallout = (data: JobDetails): MapProps.callout | undefined => {
|
|||||||
const AnchorFooter = (props: { data: JobDetails }) => {
|
const AnchorFooter = (props: { data: JobDetails }) => {
|
||||||
const { data } = props;
|
const { data } = props;
|
||||||
const [errorTips, setErrorTips] = useState<string>('');
|
const [errorTips, setErrorTips] = useState<string>('');
|
||||||
const [contactDialogVisible, setContactDialogVisible] = useState(false);
|
const [showJobContactDialog, setShowJobContactDialog] = useState(false);
|
||||||
const [showMaterialGuide, setShowMaterialGuide] = useState(false);
|
const [showMaterialGuide, setShowMaterialGuide] = useState(false);
|
||||||
const [showBuyDialog, setShowBuyDialog] = useState(false);
|
|
||||||
const [productInfo, setProductInfo] = useState<undefined | ProductInfo>();
|
const [productInfo, setProductInfo] = useState<undefined | ProductInfo>();
|
||||||
const [productRecord, setProductRecord] = useState<undefined | GetProductIsUnlockResponse>();
|
const [productRecord, setProductRecord] = useState<undefined | GetProductIsUnlockResponse>();
|
||||||
const userInfo = useUserInfo();
|
const userInfo = useUserInfo();
|
||||||
const needPhone = isNeedPhone(userInfo);
|
const needPhone = isNeedPhone(userInfo);
|
||||||
|
|
||||||
const getProductRecord = useCallback(async () => {
|
const getProductRecord = useCallback(async () => {
|
||||||
const result = await requestProductUseRecord(ProductType.VIP, { jobId: data.id });
|
const result = await requestProductUseRecord(ProductType.VIP, { jobId: data.id });
|
||||||
setProductRecord(result);
|
setProductRecord(result);
|
||||||
@ -86,6 +85,7 @@ const AnchorFooter = (props: { data: JobDetails }) => {
|
|||||||
const getProductBalance = useCallback(async () => {
|
const getProductBalance = useCallback(async () => {
|
||||||
const [, resp] = await requestProductBalance(ProductType.VIP);
|
const [, resp] = await requestProductBalance(ProductType.VIP);
|
||||||
setProductInfo(resp);
|
setProductInfo(resp);
|
||||||
|
return resp;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleClickContact = useCallback(async () => {
|
const handleClickContact = useCallback(async () => {
|
||||||
@ -126,17 +126,13 @@ const AnchorFooter = (props: { data: JobDetails }) => {
|
|||||||
jobId: data.id,
|
jobId: data.id,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
// Show material guide if no resume and no VIP and no free balance
|
||||||
if (!productInfo?.isCreateResume && !productInfo?.isPaidVip && !productInfo?.freeBalance) {
|
if (!productInfo?.isCreateResume && !productInfo?.isPaidVip && !productInfo?.freeBalance) {
|
||||||
setShowMaterialGuide(true);
|
setShowMaterialGuide(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Open integrated dialog - it handles buy + contact internally
|
||||||
if (!productRecord && !productInfo.isPaidVip && !productInfo.freeBalance) {
|
setShowJobContactDialog(true);
|
||||||
setShowBuyDialog(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setContactDialogVisible(true);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const e = error as HttpError;
|
const e = error as HttpError;
|
||||||
@ -149,33 +145,24 @@ const AnchorFooter = (props: { data: JobDetails }) => {
|
|||||||
}
|
}
|
||||||
}, [data, productInfo?.freeBalance, productInfo?.isCreateResume, productInfo?.isPaidVip]);
|
}, [data, productInfo?.freeBalance, productInfo?.isCreateResume, productInfo?.isPaidVip]);
|
||||||
|
|
||||||
const handleDialogHidden = useCallback(() => {
|
const handleDialogClose = useCallback(() => {
|
||||||
setContactDialogVisible(false);
|
setShowJobContactDialog(false);
|
||||||
}, []);
|
// Refresh data after dialog closes
|
||||||
|
getProductRecord();
|
||||||
|
}, [getProductRecord]);
|
||||||
|
|
||||||
const handleConfirmPrejob = useCallback(
|
const handleConfirmPrejob = useCallback(
|
||||||
(type: GET_CONTACT_TYPE) => {
|
(type: GET_CONTACT_TYPE) => {
|
||||||
setShowMaterialGuide(false);
|
setShowMaterialGuide(false);
|
||||||
if (GET_CONTACT_TYPE.VIP === type) {
|
if (GET_CONTACT_TYPE.VIP === type) {
|
||||||
getProductBalance();
|
getProductBalance().then(() => {
|
||||||
setContactDialogVisible(true);
|
setShowJobContactDialog(true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[getProductBalance]
|
[getProductBalance]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleAfterBuy = useCallback(async () => {
|
|
||||||
setShowBuyDialog(false);
|
|
||||||
Taro.showLoading({ mask: true, title: '加载中...' });
|
|
||||||
await getProductBalance();
|
|
||||||
console.log('购买后重新获取次数');
|
|
||||||
setContactDialogVisible(true);
|
|
||||||
Taro.hideLoading();
|
|
||||||
}, [getProductBalance]);
|
|
||||||
|
|
||||||
const handleCancel = useCallback(() => {
|
|
||||||
setShowBuyDialog(false);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// const unAuthedButtonText = useMemo(() => {
|
// const unAuthedButtonText = useMemo(() => {
|
||||||
// if (haveSeen) {
|
// if (haveSeen) {
|
||||||
// return '查看联系方式';
|
// return '查看联系方式';
|
||||||
@ -194,11 +181,8 @@ const AnchorFooter = (props: { data: JobDetails }) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Taro.eventCenter.on(EventName.CREATE_PROFILE, getProductBalance);
|
Taro.eventCenter.on(EventName.CREATE_PROFILE, getProductBalance);
|
||||||
Taro.eventCenter.on(EventName.READ_CONTACT, getProductBalance);
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
Taro.eventCenter.off(EventName.CREATE_PROFILE);
|
Taro.eventCenter.off(EventName.CREATE_PROFILE);
|
||||||
Taro.eventCenter.off(EventName.READ_CONTACT);
|
|
||||||
};
|
};
|
||||||
}, [getProductBalance]);
|
}, [getProductBalance]);
|
||||||
|
|
||||||
@ -228,12 +212,13 @@ const AnchorFooter = (props: { data: JobDetails }) => {
|
|||||||
</LoginButton>
|
</LoginButton>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{contactDialogVisible && (
|
{showJobContactDialog && (
|
||||||
<ProductContactDialog
|
<ProductJobContactDialog
|
||||||
productInfo={productInfo}
|
|
||||||
productRecord={productRecord}
|
|
||||||
data={data}
|
data={data}
|
||||||
onClose={handleDialogHidden}
|
productRecord={productRecord}
|
||||||
|
productInfo={productInfo}
|
||||||
|
onRefreshBalance={getProductBalance}
|
||||||
|
onClose={handleDialogClose}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{showMaterialGuide && (
|
{showMaterialGuide && (
|
||||||
@ -243,13 +228,6 @@ const AnchorFooter = (props: { data: JobDetails }) => {
|
|||||||
onConfirm={handleConfirmPrejob}
|
onConfirm={handleConfirmPrejob}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{showBuyDialog && (
|
|
||||||
<Dialog open onClose={handleCancel}>
|
|
||||||
<Dialog.Content>
|
|
||||||
<JobBuy onConfirm={handleAfterBuy} isCreateResume={productInfo?.isCreateResume} />
|
|
||||||
</Dialog.Content>
|
|
||||||
</Dialog>
|
|
||||||
)}
|
|
||||||
<CommonDialog
|
<CommonDialog
|
||||||
content={errorTips}
|
content={errorTips}
|
||||||
confirm="确定"
|
confirm="确定"
|
||||||
|
|||||||
Reference in New Issue
Block a user