199 lines
7.5 KiB
TypeScript
199 lines
7.5 KiB
TypeScript
import { Button, Image, Text } from '@tarojs/components';
|
||
import Taro, { useLoad } from '@tarojs/taro';
|
||
|
||
import { Cell } from '@taroify/core';
|
||
import { useCallback, useState } from 'react';
|
||
|
||
import HomePage from '@/components/home-page';
|
||
import PageLoading from '@/components/page-loading';
|
||
import { PublishJobQrCodeDialog } from '@/components/product-dialog/publish-job';
|
||
import SafeBottomPadding from '@/components/safe-bottom-padding';
|
||
import { ISelectOption, PopupSelect } from '@/components/select';
|
||
import { PageUrl } from '@/constants/app';
|
||
import { OrderStatus, OrderType, ProductSpecId, ProductType } from '@/constants/product';
|
||
import { BatchPublishGroup } from '@/types/group';
|
||
import { logWithPrefix } from '@/utils/common';
|
||
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 = 'page-user-batch-publish';
|
||
const log = logWithPrefix(PREFIX);
|
||
const SERVICE_ILLUSTRATE = `群发次数:每日一次,连发3天
|
||
群发内容:仅限主播招聘通告,违规内容不发
|
||
联系方法:通告中留通告主联系方式,主播直接联系`;
|
||
const cityValues: CityValue[] = [
|
||
{ cityCode: '440100', cityName: '广州', count: 300 },
|
||
{ cityCode: '440300', cityName: '深圳', count: 100 },
|
||
{ cityCode: '330100', cityName: '杭州', count: 300 },
|
||
{ cityCode: '110100', cityName: '北京', count: 100 },
|
||
{ cityCode: '510100', cityName: '成都', count: 50 },
|
||
{ cityCode: '430100', cityName: '长沙', count: 50 },
|
||
{ cityCode: '350200', cityName: '厦门', count: 50 },
|
||
{ cityCode: '310100', cityName: '上海', count: 100 },
|
||
{ cityCode: '420100', cityName: '武汉', count: 50 },
|
||
{ cityCode: '610100', cityName: '西安', count: 50 },
|
||
{ cityCode: '410100', cityName: '郑州', count: 100 },
|
||
].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: 100, productSpecId: ProductSpecId.GroupBatchPublish100, label: '100', price: 68 },
|
||
{ value: 300, productSpecId: ProductSpecId.GroupBatchPublish300, label: '300', price: 128 },
|
||
{ value: 500, productSpecId: ProductSpecId.GroupBatchPublish500, label: '500', price: 188 },
|
||
{ 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() {
|
||
const [loading, setLoading] = useState(true);
|
||
const [showCitySelect, setShowCitySelect] = useState(false);
|
||
const [showQrCode, setShowQrCode] = useState(false);
|
||
const [city, setCity] = useState<CityOption['value'] | null>(null);
|
||
const [cityOptions, setCityOptions] = useState<CityOption[]>([]);
|
||
const { price, originalPrice, productSpecId } = calcPrice(city);
|
||
|
||
const handleClickCity = useCallback(() => setShowCitySelect(true), []);
|
||
|
||
const handleSelectCity = useCallback(value => {
|
||
setCity(value);
|
||
setShowCitySelect(false);
|
||
}, []);
|
||
|
||
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 { 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);
|
||
}
|
||
}, [price, productSpecId]);
|
||
|
||
useLoad(async () => {
|
||
try {
|
||
const cOptions: CityOption[] = cityValues.map(value => ({ value, label: value.cityName }));
|
||
const initCity = cOptions[0].value;
|
||
|
||
setLoading(false);
|
||
setCity(initCity);
|
||
setCityOptions(cOptions);
|
||
log('init data done', cOptions);
|
||
} catch (e) {
|
||
Toast.error('加载失败请重试');
|
||
}
|
||
});
|
||
|
||
if (loading) {
|
||
return <PageLoading />;
|
||
}
|
||
|
||
return (
|
||
<HomePage>
|
||
<div className={PREFIX}>
|
||
<Image mode="widthFix" className={`${PREFIX}__header-image`} src="https://neighbourhood.cn/pubJob.png" />
|
||
<div className={`${PREFIX}__title`}>请选择城市</div>
|
||
<Cell isLink align="center" className={`${PREFIX}__cell`} title={city?.cityName} onClick={handleClickCity} />
|
||
<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>
|
||
<div className={`${PREFIX}__title`}>服务说明</div>
|
||
<div className={`${PREFIX}__illustrate`}>
|
||
<Text>{SERVICE_ILLUSTRATE}</Text>
|
||
<div className={`${PREFIX}__illustrate__describe`}>
|
||
<div>附:</div>
|
||
<div className={`${PREFIX}__illustrate__describe__view`} onClick={handleClickViewGroup}>
|
||
播络合作群列表
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<Button className={`${PREFIX}__buy-button`} onClick={handleClickBuy}>
|
||
立即购买
|
||
</Button>
|
||
<SafeBottomPadding />
|
||
<div>
|
||
<PopupSelect
|
||
value={city}
|
||
options={cityOptions}
|
||
open={showCitySelect}
|
||
onSelect={handleSelectCity}
|
||
onClose={() => setShowCitySelect(false)}
|
||
/>
|
||
<PublishJobQrCodeDialog onClose={() => setShowQrCode(false)} open={showQrCode} />
|
||
</div>
|
||
</div>
|
||
</HomePage>
|
||
);
|
||
}
|