Files
boluo-app-main/src/components/user-batch-publish/index.tsx
chashaobao 1165e027a7 feat:
2025-11-06 19:17:43 +08:00

217 lines
8.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Button } from '@tarojs/components';
import Taro from '@tarojs/taro';
import { Cell, Dialog } from '@taroify/core';
import { Fragment, useCallback, useEffect, useState } from 'react';
import PageLoading from '@/components/page-loading';
import { PublishJobQrCodeDialog } from '@/components/product-dialog/publish-job';
import CompanyPublishJobBuy from '@/components/product-dialog/steps-ui/company-publish-job-buy';
import SafeBottomPadding from '@/components/safe-bottom-padding';
import { ISelectOption } from '@/components/select';
import { PageUrl } from '@/constants/app';
import { JobManageStatus } from '@/constants/job';
import { OrderStatus, OrderType, ProductSpecId, ProductType } from '@/constants/product';
import { usePublishJob } from '@/hooks/use-publish-job';
import { BatchPublishGroup } from '@/types/group';
import { logWithPrefix } from '@/utils/common';
import { requestJobDetail } from '@/utils/job';
import {
getOrderPrice,
isCancelPay,
requestAllBuyProduct,
requestCreatePayInfo,
requestOrderInfo,
requestPayment,
} from '@/utils/product';
import { navigateTo } from '@/utils/route';
import Toast from '@/utils/toast';
import './index.less';
interface CityValue extends BatchPublishGroup {
cityName: string;
}
interface CityOption extends ISelectOption<CityValue> {
value: CityValue;
}
const PREFIX = 'user-batch-publish';
const log = logWithPrefix(PREFIX);
export const cityValues: CityValue[] = [
{ cityCode: '440100', cityName: '广州', count: 800 },
{ cityCode: '440300', cityName: '深圳', count: 100 },
{ cityCode: '330100', cityName: '杭州', count: 750 },
{ cityCode: '110100', cityName: '北京', count: 150 },
{ cityCode: '510100', cityName: '成都', count: 100 },
{ cityCode: '500100', cityName: '重庆', count: 50 },
{ cityCode: '430100', cityName: '长沙', count: 50 },
{ cityCode: '350200', cityName: '厦门', count: 50 },
{ cityCode: '310100', cityName: '上海', count: 150 },
{ cityCode: '420100', cityName: '武汉', count: 80 },
{ cityCode: '610100', cityName: '西安', count: 60 },
{ cityCode: '410100', cityName: '郑州', count: 150 },
].sort((a, b) => b.count - a.count);
const MIN_GROUP_SIZE = 20;
const GROUP_OPTIONS = [
{ value: MIN_GROUP_SIZE, productSpecId: ProductSpecId.GroupBatchPublish20, label: '20', price: 18 },
{ value: 50, productSpecId: ProductSpecId.GroupBatchPublish50, label: '50', price: 40 },
{ value: 60, productSpecId: ProductSpecId.GroupBatchPublish60, label: '60', price: 48 },
{ value: 80, productSpecId: ProductSpecId.GroupBatchPublish80, label: '80', price: 58 },
{ value: 100, productSpecId: ProductSpecId.GroupBatchPublish100, label: '100', price: 68 },
{ value: 150, productSpecId: ProductSpecId.GroupBatchPublish150, label: '150', price: 98 },
{ value: 300, productSpecId: ProductSpecId.GroupBatchPublish300, label: '300', price: 128 },
{ value: 500, productSpecId: ProductSpecId.GroupBatchPublish500, label: '500', price: 168 },
{ value: 750, productSpecId: ProductSpecId.GroupBatchPublish750, label: '750', price: 188 },
{ value: 800, productSpecId: ProductSpecId.GroupBatchPublish800, label: '800', price: 198 },
{ value: 1000, productSpecId: ProductSpecId.GroupBatchPublish1000, label: '1000', price: 288 },
];
const calcPrice = (city: CityValue | null) => {
if (!city) {
return {};
}
const { count } = city;
const originalPrice = count * 1;
const price = GROUP_OPTIONS.find(o => o.value === count)?.price || 18;
const productSpecId = GROUP_OPTIONS.find(o => o.value === count)?.productSpecId || ProductSpecId.GroupBatchPublish20;
return { price, originalPrice, productSpecId };
};
export default function UserBatchPublish({ cityCode, jobId }: { cityCode: string; jobId: string }) {
const [loading, setLoading] = useState(true);
const [showQrCode, setShowQrCode] = useState(false);
const [city, setCity] = useState<CityOption['value'] | null>(null);
const { price, originalPrice, productSpecId } = calcPrice(city);
const [showPublishJob, setShowPublishJob] = useState(false);
const [showBuy, setShowBuy, handlePublishJob] = usePublishJob(jobId);
const handleClickViewGroup = useCallback(() => navigateTo(PageUrl.GroupList, { city: city?.cityCode }), [city]);
const handleClickBuy = useCallback(async () => {
// if (1 < 2) {
// await new Promise(r => setTimeout(r, 3000));
// setShowQrCode(true);
// return;
// }
if (!price || !productSpecId) {
return;
}
try {
Taro.showLoading();
const allowBuy = await requestAllBuyProduct(ProductType.GroupBatchPublish);
if (!allowBuy) {
Taro.hideLoading();
Toast.info('您最近已购买过,可直接联系客服');
setShowQrCode(true);
return;
}
const jobDetail = await requestJobDetail(jobId);
if (jobDetail.status !== JobManageStatus.Open) {
Taro.hideLoading();
setShowPublishJob(true);
return;
}
const { payOrderNo, createPayInfo } = await requestCreatePayInfo({
type: OrderType.GroupBatchPublish,
amt: getOrderPrice(price),
// amt: 1,
productCode: ProductType.GroupBatchPublish,
productSpecId: productSpecId,
});
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');
}
Taro.hideLoading();
setShowQrCode(true);
} catch (e) {
Taro.hideLoading();
Toast.error(isCancelPay(e) ? '取消购买' : '购买失败请重试');
log('handleBuy error', e);
}
}, [jobId, price, productSpecId]);
useEffect(() => {
if (!cityCode) {
return;
}
try {
const initCity = cityValues.find(o => o.cityCode === cityCode);
setLoading(false);
if (initCity) {
setCity(initCity);
} else {
Toast.info('当前城市不支持代发');
}
} catch (e) {
Toast.error('加载失败请重试');
}
}, [cityCode]);
if (loading) {
return <PageLoading />;
}
return (
<div className={PREFIX}>
{/*<Image mode="widthFix" className={`${PREFIX}__header-image`} src="https://neighbourhood.cn/pubJob.png" />*/}
<div className={`${PREFIX}__title`}></div>
<div className={`${PREFIX}__illustrate`}>
<div className="underline"></div>
</div>
<div className={`${PREFIX}__title`}></div>
<Cell align="center" className={`${PREFIX}__cell`} title={city ? city.cityName : '暂不支持代发'} />
{city && (
<Fragment>
<div className={`${PREFIX}__extra`} onClick={handleClickViewGroup}>
</div>
<div className={`${PREFIX}__title`}></div>
<Cell align="center" className={`${PREFIX}__cell`} title={city?.count} />
<div className={`${PREFIX}__title`}></div>
<div className={`${PREFIX}__cost-describe`}>
<div className={`${PREFIX}__cost-describe__price`}>{`${price}`}</div>
<div className={`${PREFIX}__cost-describe__original_price`}>{`原价:${originalPrice}`}</div>
</div>
<Button className={`${PREFIX}__buy-button`} onClick={handleClickBuy}>
</Button>
</Fragment>
)}
<SafeBottomPadding />
<div>
<PublishJobQrCodeDialog onClose={() => setShowQrCode(false)} open={showQrCode} />
<Dialog open={showBuy} onClose={() => setShowBuy(false)}>
<Dialog.Content>
<CompanyPublishJobBuy onNext={handlePublishJob} />
</Dialog.Content>
</Dialog>
<Dialog open={showPublishJob} onClose={() => setShowPublishJob(false)}>
<Dialog.Content>
<div className={`${PREFIX}__publish-title`}></div>
<Button className={`${PREFIX}__publish-button`} onClick={handlePublishJob}>
</Button>
</Dialog.Content>
</Dialog>
</div>
</div>
);
}