- {LIST.map(item => (
+ {productList.map(item => (
handleClickItem(item)}
+ onClick={item.payPrice === 0 ? undefined : () => handleClickItem(item)}
>
-
+
{item.title}
-
{item.price}
+
{item.priceText}
{item.badge &&
}
))}
@@ -152,20 +181,24 @@ export default function CompanyPublishJobBuy(props: IProps) {
包含
-
- {selectItem.contents.map(i => (
-
- {i.content}
- {i.inlineHighlight &&
{i.inlineHighlight}
}
+ {selectItem && (
+
+
+ {getJsonContent(selectItem.contentsJson).map(i => (
+
+ {i.content}
+ {i.inlineHighlight &&
{i.inlineHighlight}
}
+
+ ))}
- ))}
-
-
+
+
+ )}
);
}
diff --git a/src/components/product-dialog/steps-ui/job-buy.tsx b/src/components/product-dialog/steps-ui/job-buy.tsx
index 301103c..bb0bcdb 100644
--- a/src/components/product-dialog/steps-ui/job-buy.tsx
+++ b/src/components/product-dialog/steps-ui/job-buy.tsx
@@ -6,51 +6,59 @@ import { useCallback, useEffect, useState } from 'react';
import Badge from '@/components/badge';
import { PREFIX } from '@/components/product-dialog/const';
+import { PageUrl } from '@/constants/app';
import { CollectEventName } from '@/constants/event';
-import { OrderStatus, OrderType, ProductSpecId, ProductType } from '@/constants/product';
+import { OrderStatus, OrderType, ProductType } from '@/constants/product';
import { SubscribeTempId } from '@/constants/subscribe';
+import { ProductSpecResult } from '@/types/product';
import { logWithPrefix } from '@/utils/common';
import { collectEvent } from '@/utils/event';
-import { getOrderPrice, isCancelPay, requestCreatePayInfo, requestOrderInfo, requestPayment } from '@/utils/product';
+import {
+ isCancelPay,
+ requestCreatePayInfo,
+ requestOrderInfo,
+ requestPayment,
+ requestProductTypeList,
+} from '@/utils/product';
+import { navigateTo } from '@/utils/route';
import { postSubscribe, subscribeMessage } from '@/utils/subscribe';
import Toast from '@/utils/toast';
interface IProps {
- buyOnly?: boolean;
onConfirm: () => void;
}
-interface Item {
- id: ProductSpecId;
- title: string;
- content: string;
- buyOnlyContent?: string;
- price: string;
- amt: number;
- badge?: string;
-}
+// interface Item {
+// id: ProductSpecId;
+// title: string;
+// content: string;
+// buyOnlyContent?: string;
+// price: string;
+// amt: number;
+// badge?: string;
+// }
-const LIST: Item[] = [
- { id: ProductSpecId.WeeklyVIP, title: '非会员', content: '每日2次', price: '免费', amt: 0 },
- {
- id: ProductSpecId.DailyVIP,
- title: '日会员',
- content: '每日+10次',
- buyOnlyContent: '每日12次',
- price: '60播豆',
- amt: 6,
- badge: '限时体验',
- },
- {
- id: ProductSpecId.WeeklyVIP,
- title: '周会员',
- content: '每日+10次',
- buyOnlyContent: '每日12次',
- price: '180播豆',
- amt: 18,
- badge: ' 超值',
- },
-];
+// const LIST: Item[] = [
+// { id: ProductSpecId.WeeklyVIP, title: '非会员', content: '每日2次', price: '免费', amt: 0 },
+// {
+// id: ProductSpecId.DailyVIP,
+// title: '日会员',
+// content: '每日+10次',
+// buyOnlyContent: '每日12次',
+// price: '60播豆',
+// amt: 6,
+// badge: '限时体验',
+// },
+// {
+// id: ProductSpecId.WeeklyVIP,
+// title: '周会员',
+// content: '每日+10次',
+// buyOnlyContent: '每日12次',
+// price: '180播豆',
+// amt: 18,
+// badge: ' 超值',
+// },
+// ];
const log = logWithPrefix('job-buy');
const SUBSCRIBE_ID = SubscribeTempId.SUBSCRIBE_VIP;
@@ -66,20 +74,26 @@ const subscribe = async () => {
};
export default function JobBuy(props: IProps) {
- const { onConfirm, buyOnly } = props;
- const [selectItem, setSelectItem] = useState(LIST[1]);
+ const { onConfirm } = props;
+ const [productList, setProductList] = useState
([]);
+ const [selectItem, setSelectItem] = useState();
- const handleClickItem = useCallback((newSelectItem: Item) => setSelectItem(newSelectItem), []);
+ const handleClickItem = useCallback((newSelectItem: ProductSpecResult) => setSelectItem(newSelectItem), []);
const handleBuy = useCallback(async () => {
log('handleBuy', selectItem);
+ if (!selectItem) {
+ Toast.error('请选择购买的产品');
+ return;
+ }
try {
Taro.showLoading();
+
const { payOrderNo, createPayInfo } = await requestCreatePayInfo({
type: OrderType.VIP,
- amt: getOrderPrice(selectItem.amt),
+ amt: selectItem.payPrice,
productCode: ProductType.VIP,
- productSpecId: selectItem.id,
+ productSpecId: selectItem.productSpecId,
});
log('handleBuy payInfo', payOrderNo, createPayInfo);
await requestPayment({
@@ -104,59 +118,65 @@ export default function JobBuy(props: IProps) {
}
}, [selectItem, onConfirm]);
+ const handleGetProductInfo = useCallback(async () => {
+ const result = await requestProductTypeList(ProductType.VIP);
+ setProductList(result);
+ setSelectItem(result[0]);
+ }, []);
+
+ const handleResume = useCallback(() => {
+ navigateTo(PageUrl.MaterialUploadVideo);
+ }, []);
+
useEffect(() => {
+ handleGetProductInfo();
collectEvent(CollectEventName.CREATE_ORDER_VIEW, { orderType: OrderType.VIP });
}, []);
return (
- {buyOnly ? (
-
开通播络会员即可直接查看联系方式
- ) : (
-
-
今日通告对接次数
-
已用完
+
+
+
完善模卡
+
赠10次查看
+
+ 去完善
- )}
- {buyOnly ? (
-
每天可获取12个联系方式
- ) : (
-
- )}
+
- {LIST.map(item => {
- if (buyOnly && !item.amt) {
- return null;
- }
+ {productList.map(item => {
return (
handleClickItem(item)}
+ onClick={item.payPrice === 0 ? undefined : () => handleClickItem(item)}
>
-
+
{item.title}
-
{buyOnly ? item.buyOnlyContent : item.content}
-
{item.price}
+
{item.contentSingle}
+
{item.showPrice}元
{item.badge &&
}
);
})}
-
-
diff --git a/src/components/product-dialog/steps-ui/job-contact-direct.tsx b/src/components/product-dialog/steps-ui/job-contact-direct.tsx
index 57b3231..e997753 100644
--- a/src/components/product-dialog/steps-ui/job-contact-direct.tsx
+++ b/src/components/product-dialog/steps-ui/job-contact-direct.tsx
@@ -10,7 +10,7 @@ interface IContactDirectProps {
}
export default function ContactDirect(props: IContactDirectProps) {
- const { publisherAcctNo, onAfterConfirm, onReport } = props;
+ const { publisherAcctNo, onAfterConfirm } = props;
const handleCopyAndContact = async () => {
await copy(publisherAcctNo);
diff --git a/src/constants/app.ts b/src/constants/app.ts
index 0b40374..2022998 100644
--- a/src/constants/app.ts
+++ b/src/constants/app.ts
@@ -17,6 +17,7 @@ export enum EventName {
ADD_GROUP = 'add_group',
SELECT_CITY = 'select_city',
CREATE_PROFILE = 'create_profile',
+ READ_CONTACT = 'read_contact',
UPDATE_PROFILE = 'update_profile',
EDIT_JOB_DESCRIBE = 'edit_job_describe',
JOB_UPDATE = 'job_update',
diff --git a/src/pages/job-detail/index.less b/src/pages/job-detail/index.less
index 871e0f8..1a16fec 100644
--- a/src/pages/job-detail/index.less
+++ b/src/pages/job-detail/index.less
@@ -269,6 +269,21 @@
flex: 2 2;
.button(@height: 88px; @fontSize: 32px; @fontWeight: 500; @borderRadius: 44px;);
margin-left: 32px;
+ position: relative;
+ overflow: visible;
+
+ &-tag {
+ position: absolute;
+ right: 8px;
+ top: -12px;
+ font-weight: 400;
+ font-size: 24px;
+ line-height: 32px;
+ color: #FFFFFF;
+ padding: 2px 8px;
+ background: #FF5051;
+ border-radius: 20px 24px 24px 0px;
+ }
}
-}
\ No newline at end of file
+}
diff --git a/src/pages/job-detail/index.tsx b/src/pages/job-detail/index.tsx
index 8114e77..0f22a4f 100644
--- a/src/pages/job-detail/index.tsx
+++ b/src/pages/job-detail/index.tsx
@@ -12,8 +12,9 @@ import { JoinGroupHint } from '@/components/join-group-hint';
import LoginButton from '@/components/login-button';
import PageLoading from '@/components/page-loading';
import { PrejobPopup } from '@/components/prejob-popup';
-import ProductJobDialog from '@/components/product-dialog/job';
+import ProductContactDialog from '@/components/product-dialog/contact';
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 { CertificationStatusType } from '@/constants/company';
import { ReportEventId } from '@/constants/event';
@@ -27,6 +28,7 @@ import { RESPONSE_ERROR_CODE } from '@/http/constant';
import { HttpError } from '@/http/error';
import { JobDetails } from '@/types/job';
import { IMaterialMessage } from '@/types/message';
+import { ProductInfo } from '@/types/product';
import { switchRoleType } from '@/utils/app';
import { copy, logWithPrefix } from '@/utils/common';
import { reportEvent } from '@/utils/event';
@@ -35,13 +37,11 @@ import { calcDistance, isValidLocation } from '@/utils/location';
import { requestProfileDetail } from '@/utils/material';
import { isChatWithSelf, postCreateChat } from '@/utils/message';
import { getInviteCodeFromQueryAndUpdate } from '@/utils/partner';
-import { requestProductBalance, requestProductUseRecord } from '@/utils/product';
+import { requestProductBalance } from '@/utils/product';
import { getJumpUrl, getPageQuery, navigateTo } from '@/utils/route';
import { getCommonShareMessage } from '@/utils/share';
import { formatDate } from '@/utils/time';
import Toast from '@/utils/toast';
-import { isNeedCreateMaterial } from '@/utils/user';
-
import './index.less';
const PREFIX = 'job-detail';
@@ -70,8 +70,15 @@ const getMapCallout = (data: JobDetails): MapProps.callout | undefined => {
const AnchorFooter = (props: { data: JobDetails }) => {
const { data } = props;
const [errorTips, setErrorTips] = useState
('');
- const [dialogVisible, setDialogVisible] = useState(false);
+ const [contactDialogVisible, setContactDialogVisible] = useState(false);
const [showMaterialGuide, setShowMaterialGuide] = useState(false);
+ const [showBuyDialog, setShowBuyDialog] = useState(false);
+ const [productInfo, setProductInfo] = useState();
+
+ const getProductBalance = useCallback(async () => {
+ const [, resp] = await requestProductBalance(ProductType.VIP);
+ setProductInfo(resp);
+ }, [data.id]);
const handleClickContact = useCallback(async () => {
log('handleClickContact');
@@ -79,21 +86,8 @@ const AnchorFooter = (props: { data: JobDetails }) => {
return;
}
reportEvent(ReportEventId.CLICK_JOB_CONTACT);
- try {
- const needCreateMaterial = await isNeedCreateMaterial();
- if (data.sourcePlat !== 'bl') {
- if (needCreateMaterial) {
- const result = await requestProductUseRecord(ProductType.VIP, { jobId: data.id });
- if (!result) {
- const [time, isPaidVip] = await requestProductBalance(ProductType.VIP);
- if (time <= 0 || !isPaidVip) {
- setShowMaterialGuide(true);
- return;
- }
- }
- }
- }
+ try {
if (data.isAuthed) {
const toUserId = data.userId;
if (isChatWithSelf(toUserId)) {
@@ -102,7 +96,7 @@ const AnchorFooter = (props: { data: JobDetails }) => {
}
const chat = await postCreateChat(toUserId);
let materialMessage: null | IMaterialMessage = null;
- if (!needCreateMaterial) {
+ if (!!productInfo?.isCreateResume) {
const profile = await requestProfileDetail();
if (profile) {
materialMessage = {
@@ -124,7 +118,17 @@ const AnchorFooter = (props: { data: JobDetails }) => {
jobId: data.id,
});
} else {
- setDialogVisible(true);
+ if (!productInfo?.isCreateResume && !productInfo?.isPaidVip && !productInfo?.freeBalance) {
+ setShowMaterialGuide(true);
+ return;
+ }
+
+ if (!productInfo.isPaidVip && !productInfo.freeBalance) {
+ setShowBuyDialog(true);
+ return;
+ }
+
+ setContactDialogVisible(true);
}
} catch (error) {
const e = error as HttpError;
@@ -135,17 +139,57 @@ const AnchorFooter = (props: { data: JobDetails }) => {
Toast.error('请求失败请重试');
}
}
- }, [data]);
+ }, [data, productInfo?.freeBalance, productInfo?.isCreateResume, productInfo?.isPaidVip]);
const handleDialogHidden = useCallback(() => {
- setDialogVisible(false);
+ setContactDialogVisible(false);
}, []);
- const handleConfirmPrejob = useCallback((type: GET_CONTACT_TYPE) => {
- setShowMaterialGuide(false);
- if (GET_CONTACT_TYPE.VIP === type) {
- setDialogVisible(true);
- }
+ const handleConfirmPrejob = useCallback(
+ (type: GET_CONTACT_TYPE) => {
+ setShowMaterialGuide(false);
+ if (GET_CONTACT_TYPE.VIP === type) {
+ getProductBalance();
+ setContactDialogVisible(true);
+ }
+ },
+ [getProductBalance]
+ );
+
+ const handleAfterBuy = useCallback(() => {
+ setShowBuyDialog(false);
+ getProductBalance();
+ setContactDialogVisible(true);
+ }, [getProductBalance]);
+
+ const handleCancel = useCallback(() => {
+ setShowBuyDialog(false);
}, []);
+
+ // const unAuthedButtonText = useMemo(() => {
+ // if (haveSeen) {
+ // return '查看联系方式';
+ // }
+ //
+ // if (productInfo?.isPaidVip) {
+ // return '您是会员,可直接查看';
+ // }
+ //
+ // if (productInfo?.freeBalance) {
+ // return `还剩${productInfo.freeBalance}次查看次数`;
+ // }
+ //
+ // return productInfo?.isCreateResume? '升级会员即可查看': '创建模卡,免费查看';
+ // }, [productInfo, haveSeen]);
+
+ useEffect(() => {
+ Taro.eventCenter.on(EventName.CREATE_PROFILE, getProductBalance);
+ Taro.eventCenter.on(EventName.READ_CONTACT, getProductBalance);
+ }, []);
+
+ useEffect(() => {
+ getProductBalance();
+ }, [getProductBalance]);
+
return (
<>
@@ -153,14 +197,28 @@ const AnchorFooter = (props: { data: JobDetails }) => {
分享
- {data.isAuthed ? '急招岗位可免费查看' : '查看联系方式'}
+ {data.isAuthed ? '在线沟通' : '查看联系方式'}
+ {data.isAuthed || productInfo?.content ? (
+
+ {data.isAuthed ? '急招岗位可免费查看' : productInfo?.content}
+
+ ) : null}
- {dialogVisible &&
}
+ {contactDialogVisible && (
+
+ )}
{showMaterialGuide && (
setShowMaterialGuide(false)} onConfirm={handleConfirmPrejob} />
)}
+ {showBuyDialog && (
+
+ )}
(buildUrl(API.LIST_PRODUCT_TYPE, { productType }));
+ const list = await http.get(buildUrl(API.LIST_PRODUCT_TYPE, { productType }));
+ return list.sort((a, b) => a.sort - b.sort);
}
// 使用某一个产品
@@ -59,13 +61,14 @@ export async function requestUseProduct(
}
// 获取某个产品的剩余解锁次数
-export async function requestProductBalance(productCode: ProductType): Promise<[number, boolean | undefined]> {
+export async function requestProductBalance(productCode: ProductType): Promise<[number, ProductInfo]> {
const data: GetProductDetailRequest = { productCode, userId: getUserId() };
- const { balance, isPaidVip } = await http.post(API.GET_PRODUCT_DETAIL, {
+ const result = await http.post(API.GET_PRODUCT_DETAIL, {
data,
contentType: 'application/x-www-form-urlencoded',
});
- return [balance, isPaidVip];
+
+ return [result.balance, result];
}
// 是否可以购买某一个产品