162 lines
5.3 KiB
TypeScript
162 lines
5.3 KiB
TypeScript
import Taro from '@tarojs/taro';
|
|
|
|
import { Button } from '@taroify/core';
|
|
import classNames from 'classnames';
|
|
import { useCallback, useEffect, useState } from 'react';
|
|
|
|
import Badge from '@/components/badge';
|
|
import { PREFIX } from '@/components/product-dialog/const';
|
|
import { CollectEventName } from '@/constants/event';
|
|
import { OrderStatus, OrderType, ProductSpecId, ProductType } from '@/constants/product';
|
|
import { SubscribeTempId } from '@/constants/subscribe';
|
|
import { logWithPrefix } from '@/utils/common';
|
|
import { collectEvent } from '@/utils/event';
|
|
import { getOrderPrice, isCancelPay, requestCreatePayInfo, requestOrderInfo, requestPayment } from '@/utils/product';
|
|
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;
|
|
}
|
|
|
|
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;
|
|
|
|
const subscribe = async () => {
|
|
const result = await subscribeMessage([SUBSCRIBE_ID]);
|
|
const success = result[SUBSCRIBE_ID] === 'accept';
|
|
if (!success) {
|
|
postSubscribe([SUBSCRIBE_ID], []);
|
|
return;
|
|
}
|
|
postSubscribe([SUBSCRIBE_ID], [SUBSCRIBE_ID]);
|
|
};
|
|
|
|
export default function JobBuy(props: IProps) {
|
|
const { onConfirm, buyOnly } = props;
|
|
const [selectItem, setSelectItem] = useState(LIST[1]);
|
|
|
|
const handleClickItem = useCallback((newSelectItem: Item) => setSelectItem(newSelectItem), []);
|
|
|
|
const handleBuy = useCallback(async () => {
|
|
log('handleBuy', selectItem);
|
|
try {
|
|
Taro.showLoading();
|
|
const { payOrderNo, createPayInfo } = await requestCreatePayInfo({
|
|
type: OrderType.VIP,
|
|
amt: getOrderPrice(selectItem.amt),
|
|
productCode: ProductType.VIP,
|
|
productSpecId: selectItem.id,
|
|
});
|
|
log('handleBuy payInfo', payOrderNo, createPayInfo);
|
|
await requestPayment({
|
|
timeStamp: createPayInfo.timeStamp,
|
|
nonceStr: createPayInfo.nonceStr,
|
|
package: createPayInfo.packageVal,
|
|
signType: createPayInfo.signType,
|
|
paySign: createPayInfo.paySign,
|
|
success: () => subscribe(),
|
|
});
|
|
const { status } = await requestOrderInfo({ payOrderNo });
|
|
log('handleBuy orderInfo', status);
|
|
if (status !== OrderStatus.Success) {
|
|
throw new Error('order status error');
|
|
}
|
|
Taro.hideLoading();
|
|
onConfirm();
|
|
} catch (e) {
|
|
Taro.hideLoading();
|
|
Toast.error(isCancelPay(e) ? '取消购买' : '购买失败请重试');
|
|
log('handleBuy error', e);
|
|
}
|
|
}, [selectItem, onConfirm]);
|
|
|
|
useEffect(() => {
|
|
collectEvent(CollectEventName.CREATE_ORDER_VIEW, { orderType: OrderType.VIP });
|
|
}, []);
|
|
|
|
return (
|
|
<div className={`${PREFIX}__job-buy`}>
|
|
{buyOnly ? (
|
|
<div className={`${PREFIX}__job-buy__header`}>开通播络会员即可直接查看联系方式</div>
|
|
) : (
|
|
<div className={`${PREFIX}__job-buy__header`}>
|
|
<div>今日通告对接次数</div>
|
|
<div className="highlight">已用完</div>
|
|
</div>
|
|
)}
|
|
{buyOnly ? (
|
|
<div className={`${PREFIX}__job-buy__describe`}>每天可获取12个联系方式</div>
|
|
) : (
|
|
<div className={`${PREFIX}__job-buy__describe`}>
|
|
<div>请</div>
|
|
<div className="highlight">明日</div>
|
|
<div>再来 或 </div>
|
|
<div className="highlight">升级会员</div>
|
|
</div>
|
|
)}
|
|
<div className={`${PREFIX}__job-buy__container`}>
|
|
{LIST.map(item => {
|
|
if (buyOnly && !item.amt) {
|
|
return null;
|
|
}
|
|
return (
|
|
<div
|
|
key={item.price}
|
|
className={classNames(`${PREFIX}__job-buy__item`, {
|
|
selected: item.amt === selectItem.amt,
|
|
disabled: item.amt === 0,
|
|
})}
|
|
onClick={item.amt === 0 ? undefined : () => handleClickItem(item)}
|
|
>
|
|
<div className={classNames(`${PREFIX}__job-buy__item__title`, { free: item.amt === 0 })}>
|
|
{item.title}
|
|
</div>
|
|
<div className={`${PREFIX}__job-buy__item__content`}>{buyOnly ? item.buyOnlyContent : item.content}</div>
|
|
<div className={`${PREFIX}__job-buy__item__price`}>{item.price}</div>
|
|
{item.badge && <Badge className={`${PREFIX}__job-buy__item__badge`} text={item.badge} />}
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
<Button className={`${PREFIX}__job-buy__button`} onClick={handleBuy}>
|
|
{`支付 ${selectItem.amt} 元`}
|
|
</Button>
|
|
{/* <div className={`${PREFIX}__job-buy__tips`}>{`已选:${selectItem.title},含进本地群服务`}</div> */}
|
|
</div>
|
|
);
|
|
}
|