Files
boluo-app-main/src/components/product-dialog/steps-ui/group-buy.tsx
2025-03-31 22:34:22 +08:00

111 lines
3.6 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 { logWithPrefix } from '@/utils/common';
import { collectEvent } from '@/utils/event';
import {
getOrderPrice,
requestCreatePayInfo,
requestOrderInfo,
requestPayment,
requestProductBalance,
} from '@/utils/product';
import Toast from '@/utils/toast';
interface IProps {
source: 'group-list' | 'job-detail';
onConfirm: (time: number) => void;
}
interface Item {
id: ProductSpecId;
num: number;
price: number;
badge?: string;
}
const LIST: Item[] = [
{ id: ProductSpecId.AddGroup1, num: 1, price: 2 },
{ id: ProductSpecId.AddGroup2, num: 2, price: 3, badge: '7.5折' },
{ id: ProductSpecId.AddGroup3, num: 5, price: 6, badge: '6折' },
];
const log = logWithPrefix('group-buy');
export default function GroupBuy(props: IProps) {
const { source, onConfirm } = props;
const [selectItem, setSelectItem] = useState(LIST[2]);
const handleClickItem = useCallback((newSelectItem: Item) => setSelectItem(newSelectItem), []);
const handleBuy = useCallback(async () => {
log('handleBuy', selectItem);
try {
Taro.showLoading();
const { payOrderNo, createPayInfo } = await requestCreatePayInfo({
type: OrderType.Group,
amt: getOrderPrice(selectItem.price),
// amt: selectItem.price,
// amt: 1,
productCode: ProductType.AddGroup,
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,
});
const { status } = await requestOrderInfo({ payOrderNo });
log('handleBuy orderInfo', status);
if (status !== OrderStatus.Success) {
throw new Error('order status error');
}
const time = await requestProductBalance(ProductType.AddGroup);
log('handleBuy new addGroupTime', time);
onConfirm(time);
} catch (e) {
Toast.error('购买失败!');
log('handleBuy error', e);
} finally {
Taro.hideLoading();
}
}, [selectItem, onConfirm]);
useEffect(() => {
collectEvent(CollectEventName.CREATE_ORDER_VIEW, { orderType: OrderType.Group, source });
}, [source]);
return (
<div className={`${PREFIX}__group-buy`}>
<div className={`${PREFIX}__group-buy__header`}></div>
<div className={`${PREFIX}__group-buy__container`}>
{LIST.map(item => (
<div
key={item.price}
className={classNames(`${PREFIX}__group-buy__item`, { selected: item.price === selectItem.price })}
onClick={() => handleClickItem(item)}
>
<div className={`${PREFIX}__group-buy__item-title`}>{`${item.num}`}</div>
<div className={`${PREFIX}__group-buy__item-price`}>{`${item.price}`}</div>
{item.badge && <Badge text={item.badge} />}
</div>
))}
</div>
<Button className={`${PREFIX}__group-buy__button`} onClick={handleBuy}>
{`支付 ${selectItem.price}`}
</Button>
<div className={`${PREFIX}__group-buy__tips`}>{`已选:${selectItem.num}`}</div>
</div>
);
}