feat: 代招代发
This commit is contained in:
@ -6,12 +6,12 @@
|
|||||||
height: 152px;
|
height: 152px;
|
||||||
.flex-row();
|
.flex-row();
|
||||||
padding: 24px 32px;
|
padding: 24px 32px;
|
||||||
background: #FFF;
|
background: #fff;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
content: "";
|
content: '';
|
||||||
height: 2px;
|
height: 2px;
|
||||||
background: #00000026;
|
background: #00000026;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -52,7 +52,11 @@
|
|||||||
|
|
||||||
&__status {
|
&__status {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
.flex-row();
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-end;
|
||||||
|
gap: 24px;
|
||||||
font-size: 28px;
|
font-size: 28px;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
@ -63,7 +67,27 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.error {
|
&.error {
|
||||||
color: #FF5051;
|
color: #ff5051;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
&__buy-tag {
|
||||||
|
padding: 8px;
|
||||||
|
background: rgba(255, 80, 81, 0.12);
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
color: #ff5051;
|
||||||
|
.flex-row();
|
||||||
|
|
||||||
|
&-wrapper {
|
||||||
|
padding-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-icon {
|
||||||
|
width: 13px;
|
||||||
|
height: 18px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
|
import { Image } from '@tarojs/components';
|
||||||
|
|
||||||
|
import { Arrow } from '@taroify/icons';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { cityValues } from '@/components/user-batch-publish';
|
||||||
import { PageUrl } from '@/constants/app';
|
import { PageUrl } from '@/constants/app';
|
||||||
import { JOB_MANAGE_STATUS_TITLE_MAP, JobManageStatus } from '@/constants/job';
|
import { JOB_MANAGE_STATUS_TITLE_MAP, JobManageStatus } from '@/constants/job';
|
||||||
import { JobManageInfo } from '@/types/job';
|
import { JobManageInfo } from '@/types/job';
|
||||||
@ -25,6 +29,29 @@ const STATUS_CLASS_MAP = {
|
|||||||
[JobManageStatus.Expire]: 'close',
|
[JobManageStatus.Expire]: 'close',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function GoBatchTag({ cityCode, jobId }: { cityCode: string; jobId: JobManageInfo['id'] }) {
|
||||||
|
const handleClick = useCallback(
|
||||||
|
e => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
navigateTo(PageUrl.GroupDelegatePublish, { cityCode, jobId });
|
||||||
|
},
|
||||||
|
[cityCode, jobId]
|
||||||
|
);
|
||||||
|
if (!cityValues.find(c => c.cityCode === cityCode)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div onClick={handleClick} className={`${PREFIX}__buy-tag-wrapper`}>
|
||||||
|
<div className={`${PREFIX}__buy-tag`}>
|
||||||
|
<Image className={`${PREFIX}__buy-tag-icon`} src="https://publiccdn.neighbourhood.com.cn/img/lightning.svg" />
|
||||||
|
<div>加速招聘</div>
|
||||||
|
<Arrow size={12} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function JobManageCard(props: IProps) {
|
function JobManageCard(props: IProps) {
|
||||||
const { data = {} } = props;
|
const { data = {} } = props;
|
||||||
const { id, title, status } = data as JobManageInfo;
|
const { id, title, status } = data as JobManageInfo;
|
||||||
@ -41,6 +68,7 @@ function JobManageCard(props: IProps) {
|
|||||||
</div>
|
</div>
|
||||||
<div className={classNames(`${PREFIX}__status`, { [STATUS_CLASS_MAP[status]]: true })}>
|
<div className={classNames(`${PREFIX}__status`, { [STATUS_CLASS_MAP[status]]: true })}>
|
||||||
<div>{JOB_MANAGE_STATUS_TITLE_MAP[status]}</div>
|
<div>{JOB_MANAGE_STATUS_TITLE_MAP[status]}</div>
|
||||||
|
<GoBatchTag cityCode={props.data.cityCode} jobId={props.data.id} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -13,9 +13,9 @@
|
|||||||
&__title {
|
&__title {
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
line-height: 48px;
|
line-height: 48px;
|
||||||
font-weight: 500;
|
margin-top: 32px;
|
||||||
color: @blColor;
|
font-weight: 400;
|
||||||
margin-top: 24px;
|
color: #1d2129;
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
@ -30,13 +30,21 @@
|
|||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__extra {
|
||||||
|
margin-top: 24px;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 40px;
|
||||||
|
color: @blHighlightColor;
|
||||||
|
}
|
||||||
|
|
||||||
&__cost-describe {
|
&__cost-describe {
|
||||||
height: 100px;
|
height: 100px;
|
||||||
padding: 0 32px;
|
padding: 0 32px;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
.flex-row();
|
.flex-row();
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
background: #FFFFFF;
|
background: #ffffff;
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
|
|
||||||
&__price {
|
&__price {
|
||||||
@ -64,9 +72,22 @@
|
|||||||
line-height: 48px;
|
line-height: 48px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
color: @blColorG2;
|
color: @blColorG2;
|
||||||
background: #FFFFFF;
|
background: #ffffff;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
|
|
||||||
|
.underline {
|
||||||
|
display: inline;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 32px;
|
||||||
|
line-height: 48px;
|
||||||
|
color: @blColor;
|
||||||
|
position: relative;
|
||||||
|
background-image: linear-gradient(to bottom, rgba(109, 61, 245, 0.6) 0%, rgba(109, 61, 245, 0.6) 100%);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 100% 12px;
|
||||||
|
background-position: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
&__describe {
|
&__describe {
|
||||||
.flex-row();
|
.flex-row();
|
||||||
font-size: 28px;
|
font-size: 28px;
|
||||||
@ -86,4 +107,16 @@
|
|||||||
.button(@width: 100%; @height: 80px; @fontSize: 32px);
|
.button(@width: 100%; @height: 80px; @fontSize: 32px);
|
||||||
margin-top: 40px;
|
margin-top: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__publish-title {
|
||||||
|
font-size: 36px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 56px;
|
||||||
|
color: @blColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__publish-button {
|
||||||
|
.button(@width: 360px, @height: 72px, @fontSize: 28px, @fontWeight: 400, @borderRadius: 44px);
|
||||||
|
margin: 40px auto auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,21 @@
|
|||||||
import { Button, Text } from '@tarojs/components';
|
import { Button } from '@tarojs/components';
|
||||||
import Taro from '@tarojs/taro';
|
import Taro from '@tarojs/taro';
|
||||||
|
|
||||||
import { Cell } from '@taroify/core';
|
import { Cell, Dialog } from '@taroify/core';
|
||||||
import { useCallback, useState, useEffect } from 'react';
|
import { Fragment, useCallback, useEffect, useState } from 'react';
|
||||||
|
|
||||||
import PageLoading from '@/components/page-loading';
|
import PageLoading from '@/components/page-loading';
|
||||||
import { PublishJobQrCodeDialog } from '@/components/product-dialog/publish-job';
|
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 SafeBottomPadding from '@/components/safe-bottom-padding';
|
||||||
import { ISelectOption, PopupSelect } from '@/components/select';
|
import { ISelectOption } from '@/components/select';
|
||||||
import { PageUrl } from '@/constants/app';
|
import { PageUrl } from '@/constants/app';
|
||||||
|
import { JobManageStatus } from '@/constants/job';
|
||||||
import { OrderStatus, OrderType, ProductSpecId, ProductType } from '@/constants/product';
|
import { OrderStatus, OrderType, ProductSpecId, ProductType } from '@/constants/product';
|
||||||
|
import { usePublishJob } from '@/hooks/use-publish-job';
|
||||||
import { BatchPublishGroup } from '@/types/group';
|
import { BatchPublishGroup } from '@/types/group';
|
||||||
import { logWithPrefix } from '@/utils/common';
|
import { logWithPrefix } from '@/utils/common';
|
||||||
|
import { requestJobDetail } from '@/utils/job';
|
||||||
import {
|
import {
|
||||||
getOrderPrice,
|
getOrderPrice,
|
||||||
isCancelPay,
|
isCancelPay,
|
||||||
@ -22,7 +26,6 @@ import {
|
|||||||
} from '@/utils/product';
|
} from '@/utils/product';
|
||||||
import { navigateTo } from '@/utils/route';
|
import { navigateTo } from '@/utils/route';
|
||||||
import Toast from '@/utils/toast';
|
import Toast from '@/utils/toast';
|
||||||
|
|
||||||
import './index.less';
|
import './index.less';
|
||||||
|
|
||||||
interface CityValue extends BatchPublishGroup {
|
interface CityValue extends BatchPublishGroup {
|
||||||
@ -35,11 +38,7 @@ interface CityOption extends ISelectOption<CityValue> {
|
|||||||
|
|
||||||
const PREFIX = 'user-batch-publish';
|
const PREFIX = 'user-batch-publish';
|
||||||
const log = logWithPrefix(PREFIX);
|
const log = logWithPrefix(PREFIX);
|
||||||
const SERVICE_ILLUSTRATE = `服务方式:帮您把招聘需求发到众多同城合作主播群
|
export const cityValues: CityValue[] = [
|
||||||
群发次数:杭州、广州发3次,其他城市1次
|
|
||||||
内容要求:仅限带货主播招聘需求,其他不发
|
|
||||||
主播联系:内容中留招聘方联系方式,主播直接联系`;
|
|
||||||
const cityValues: CityValue[] = [
|
|
||||||
{ cityCode: '440100', cityName: '广州', count: 800 },
|
{ cityCode: '440100', cityName: '广州', count: 800 },
|
||||||
{ cityCode: '440300', cityName: '深圳', count: 100 },
|
{ cityCode: '440300', cityName: '深圳', count: 100 },
|
||||||
{ cityCode: '330100', cityName: '杭州', count: 750 },
|
{ cityCode: '330100', cityName: '杭州', count: 750 },
|
||||||
@ -79,20 +78,14 @@ const calcPrice = (city: CityValue | null) => {
|
|||||||
return { price, originalPrice, productSpecId };
|
return { price, originalPrice, productSpecId };
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function UserBatchPublish() {
|
export default function UserBatchPublish({ cityCode, jobId }: { cityCode: string; jobId: string }) {
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [showCitySelect, setShowCitySelect] = useState(false);
|
|
||||||
const [showQrCode, setShowQrCode] = useState(false);
|
const [showQrCode, setShowQrCode] = useState(false);
|
||||||
const [city, setCity] = useState<CityOption['value'] | null>(null);
|
const [city, setCity] = useState<CityOption['value'] | null>(null);
|
||||||
const [cityOptions, setCityOptions] = useState<CityOption[]>([]);
|
|
||||||
const { price, originalPrice, productSpecId } = calcPrice(city);
|
const { price, originalPrice, productSpecId } = calcPrice(city);
|
||||||
|
const [showPublishJob, setShowPublishJob] = useState(false);
|
||||||
|
|
||||||
const handleClickCity = useCallback(() => setShowCitySelect(true), []);
|
const [showBuy, setShowBuy, handlePublishJob] = usePublishJob(jobId);
|
||||||
|
|
||||||
const handleSelectCity = useCallback(value => {
|
|
||||||
setCity(value);
|
|
||||||
setShowCitySelect(false);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleClickViewGroup = useCallback(() => navigateTo(PageUrl.GroupList, { city: city?.cityCode }), [city]);
|
const handleClickViewGroup = useCallback(() => navigateTo(PageUrl.GroupList, { city: city?.cityCode }), [city]);
|
||||||
|
|
||||||
@ -114,6 +107,14 @@ export default function UserBatchPublish() {
|
|||||||
setShowQrCode(true);
|
setShowQrCode(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const jobDetail = await requestJobDetail(jobId);
|
||||||
|
|
||||||
|
if (jobDetail.status !== JobManageStatus.Open) {
|
||||||
|
setShowPublishJob(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const { payOrderNo, createPayInfo } = await requestCreatePayInfo({
|
const { payOrderNo, createPayInfo } = await requestCreatePayInfo({
|
||||||
type: OrderType.GroupBatchPublish,
|
type: OrderType.GroupBatchPublish,
|
||||||
amt: getOrderPrice(price),
|
amt: getOrderPrice(price),
|
||||||
@ -141,21 +142,25 @@ export default function UserBatchPublish() {
|
|||||||
Toast.error(isCancelPay(e) ? '取消购买' : '购买失败请重试');
|
Toast.error(isCancelPay(e) ? '取消购买' : '购买失败请重试');
|
||||||
log('handleBuy error', e);
|
log('handleBuy error', e);
|
||||||
}
|
}
|
||||||
}, [price, productSpecId]);
|
}, [jobId, price, productSpecId]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!cityCode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const cOptions: CityOption[] = cityValues.map(value => ({ value, label: value.cityName }));
|
const initCity = cityValues.find(o => o.cityCode === cityCode);
|
||||||
const initCity = (cOptions.find(o => o.label === '重庆') || cOptions[0]).value;
|
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
setCity(initCity);
|
if (initCity) {
|
||||||
setCityOptions(cOptions);
|
setCity(initCity);
|
||||||
log('init data done', cOptions);
|
} else {
|
||||||
|
Toast.info('当前城市不支持代发');
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Toast.error('加载失败请重试');
|
Toast.error('加载失败请重试');
|
||||||
}
|
}
|
||||||
}, []);
|
}, [cityCode]);
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return <PageLoading />;
|
return <PageLoading />;
|
||||||
@ -164,38 +169,46 @@ export default function UserBatchPublish() {
|
|||||||
return (
|
return (
|
||||||
<div className={PREFIX}>
|
<div className={PREFIX}>
|
||||||
{/*<Image mode="widthFix" className={`${PREFIX}__header-image`} src="https://neighbourhood.cn/pubJob.png" />*/}
|
{/*<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}__title`}>服务说明</div>
|
||||||
<div className={`${PREFIX}__illustrate`}>
|
<div className={`${PREFIX}__illustrate`}>
|
||||||
<Text>{SERVICE_ILLUSTRATE}</Text>
|
服务方式:帮您把招聘需求<div className="underline">发到本地主播群,投递量大幅增加</div>
|
||||||
<div className={`${PREFIX}__illustrate__describe`}>
|
|
||||||
<div>附:</div>
|
|
||||||
<div className={`${PREFIX}__illustrate__describe__view`} onClick={handleClickViewGroup}>
|
|
||||||
播络合作群列表
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<Button className={`${PREFIX}__buy-button`} onClick={handleClickBuy}>
|
<div className={`${PREFIX}__title`}>当前通告城市</div>
|
||||||
立即购买
|
<Cell align="center" className={`${PREFIX}__cell`} title={city ? city.cityName : '暂不支持代发'} />
|
||||||
</Button>
|
{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 />
|
<SafeBottomPadding />
|
||||||
<div>
|
<div>
|
||||||
<PopupSelect
|
|
||||||
value={city}
|
|
||||||
options={cityOptions}
|
|
||||||
open={showCitySelect}
|
|
||||||
onSelect={handleSelectCity}
|
|
||||||
onClose={() => setShowCitySelect(false)}
|
|
||||||
/>
|
|
||||||
<PublishJobQrCodeDialog onClose={() => setShowQrCode(false)} open={showQrCode} />
|
<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>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -254,9 +254,9 @@ export default function ProfileViewFragment(props: IProps) {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className={`${PREFIX}__basic-info__content`}>
|
<DevDiv className={`${PREFIX}__basic-info__content`} OnDev={onDev}>
|
||||||
<div>{getBasicInfo(profile)}</div>
|
<div>{getBasicInfo(profile)}</div>
|
||||||
</div>
|
</DevDiv>
|
||||||
<div className={`${PREFIX}__divider`} />
|
<div className={`${PREFIX}__divider`} />
|
||||||
</div>
|
</div>
|
||||||
{dataGroup.map((data, index: number) => (
|
{dataGroup.map((data, index: number) => (
|
||||||
|
|||||||
@ -48,7 +48,7 @@ const CompanyTabs: TabItemType[] = [
|
|||||||
{
|
{
|
||||||
type: PageType.BatchPublish,
|
type: PageType.BatchPublish,
|
||||||
pagePath: PageUrl.UserBatchPublish,
|
pagePath: PageUrl.UserBatchPublish,
|
||||||
text: '代招代发',
|
text: '代招',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
56
src/hooks/use-publish-job.ts
Normal file
56
src/hooks/use-publish-job.ts
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import Taro from '@tarojs/taro';
|
||||||
|
|
||||||
|
import { Dispatch, SetStateAction, useCallback, useState } from 'react';
|
||||||
|
|
||||||
|
import { EventName, PageUrl } from '@/constants/app';
|
||||||
|
import { CertificationStatusType } from '@/constants/company';
|
||||||
|
import { CollectEventName } from '@/constants/event';
|
||||||
|
import useUserInfo from '@/hooks/use-user-info';
|
||||||
|
import { RESPONSE_ERROR_CODE } from '@/http/constant';
|
||||||
|
import { HttpError } from '@/http/error';
|
||||||
|
import store from '@/store';
|
||||||
|
import { cacheJobId } from '@/store/actions';
|
||||||
|
import { collectEvent } from '@/utils/event';
|
||||||
|
import { postPublishJob } from '@/utils/job';
|
||||||
|
import { navigateTo } from '@/utils/route';
|
||||||
|
import Toast from '@/utils/toast';
|
||||||
|
|
||||||
|
export const usePublishJob = (jobId: string): [boolean, Dispatch<SetStateAction<boolean>>, () => Promise<void>] => {
|
||||||
|
const userInfo = useUserInfo();
|
||||||
|
const [showBuy, setShowBuy] = useState(false);
|
||||||
|
|
||||||
|
const handlePublishJob = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
if (userInfo.bossAuthStatus !== CertificationStatusType.Success) {
|
||||||
|
store.dispatch(cacheJobId(jobId));
|
||||||
|
navigateTo(PageUrl.CertificationStart);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Taro.showLoading();
|
||||||
|
await postPublishJob(jobId);
|
||||||
|
Taro.eventCenter.trigger(EventName.COMPANY_JOB_PUBLISH_CHANGED);
|
||||||
|
setShowBuy(false);
|
||||||
|
Toast.success('发布成功');
|
||||||
|
Taro.hideLoading();
|
||||||
|
} catch (error) {
|
||||||
|
Taro.hideLoading();
|
||||||
|
const e = error as HttpError;
|
||||||
|
const errorCode = e.errorCode;
|
||||||
|
const errorMsg = e.info?.() || e.message;
|
||||||
|
collectEvent(CollectEventName.PUBLISH_OPEN_JOB_FAILED, { jobId, error: e.info?.() || e.message });
|
||||||
|
if (errorCode === RESPONSE_ERROR_CODE.INSUFFICIENT_FREE_BALANCE) {
|
||||||
|
setShowBuy(true);
|
||||||
|
} else if (errorCode === RESPONSE_ERROR_CODE.INSUFFICIENT_BALANCE) {
|
||||||
|
Toast.info('您购买的产品已耗尽使用次数');
|
||||||
|
setShowBuy(true);
|
||||||
|
} else if (errorCode === RESPONSE_ERROR_CODE.BOSS_VIP_EXPIRED) {
|
||||||
|
Toast.info('该通告已到期,请创建新通告', 3000);
|
||||||
|
} else {
|
||||||
|
Toast.error(errorMsg || '发布失败请重试', 3000);
|
||||||
|
}
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}, [jobId, userInfo.bossAuthStatus]);
|
||||||
|
|
||||||
|
return [showBuy, setShowBuy, handlePublishJob];
|
||||||
|
};
|
||||||
@ -1,3 +1,3 @@
|
|||||||
export default definePageConfig({
|
export default definePageConfig({
|
||||||
navigationBarTitleText: '群代发',
|
navigationBarTitleText: '加速招聘',
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,12 +1,25 @@
|
|||||||
|
import { useLoad } from '@tarojs/taro';
|
||||||
|
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
import UserBatchPublish from '@/components/user-batch-publish';
|
import UserBatchPublish from '@/components/user-batch-publish';
|
||||||
|
import { getPageQuery } from '@/utils/route';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
|
|
||||||
const PREFIX = 'group-delegate-publish';
|
const PREFIX = 'group-delegate-publish';
|
||||||
|
|
||||||
export default function Partner() {
|
export default function Partner() {
|
||||||
|
const [cityCode, setCityCode] = useState('');
|
||||||
|
const [jobId, setJobId] = useState('');
|
||||||
|
|
||||||
|
useLoad(() => {
|
||||||
|
const query = getPageQuery<{ cityCode: string; jobId: string }>();
|
||||||
|
setCityCode(query.cityCode);
|
||||||
|
setJobId(query.jobId);
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<div className={PREFIX}>
|
<div className={PREFIX}>
|
||||||
<UserBatchPublish />
|
<UserBatchPublish cityCode={cityCode} jobId={jobId} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import Taro, { useShareAppMessage } from '@tarojs/taro';
|
|||||||
|
|
||||||
import { Tabs } from '@taroify/core';
|
import { Tabs } from '@taroify/core';
|
||||||
import { Arrow } from '@taroify/icons';
|
import { Arrow } from '@taroify/icons';
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { Fragment, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
import GroupCertificationList from '@/components/group-certification-list';
|
import GroupCertificationList from '@/components/group-certification-list';
|
||||||
import { EventName, OpenSource, PageUrl } from '@/constants/app';
|
import { EventName, OpenSource, PageUrl } from '@/constants/app';
|
||||||
@ -92,19 +92,21 @@ export default function GroupOwnerCertification() {
|
|||||||
<div className={`${PREFIX}__lined-title`}>选择城市,添加运营</div>
|
<div className={`${PREFIX}__lined-title`}>选择城市,添加运营</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={`${PREFIX}__city-select`} onClick={handleClickCityMenu}>
|
<div className={`${PREFIX}__city-select`} onClick={handleClickCityMenu}>
|
||||||
{CITY_CODE_TO_NAME_MAP.get(cityCode)}
|
{CITY_CODE_TO_NAME_MAP.get(cityCode) || '请选择城市'}
|
||||||
<Arrow size={16} />
|
<Arrow size={16} />
|
||||||
</div>
|
</div>
|
||||||
<div className={`${PREFIX}__lined-wrapper`}>
|
|
||||||
<div className={`${PREFIX}__lined-title`}>长按并识别二维码添加运营</div>
|
|
||||||
</div>
|
|
||||||
{staffInfo && (
|
{staffInfo && (
|
||||||
<Image
|
<Fragment>
|
||||||
className={`${PREFIX}__qrcode`}
|
<div className={`${PREFIX}__lined-wrapper`}>
|
||||||
src={staffInfo.staffQrCode}
|
<div className={`${PREFIX}__lined-title`}>长按并识别二维码添加运营</div>
|
||||||
showMenuByLongpress
|
</div>
|
||||||
mode="aspectFill"
|
<Image
|
||||||
/>
|
className={`${PREFIX}__qrcode`}
|
||||||
|
src={staffInfo.staffQrCode}
|
||||||
|
showMenuByLongpress
|
||||||
|
mode="aspectFill"
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className={`${PREFIX}__title`}>第二步</div>
|
<div className={`${PREFIX}__title`}>第二步</div>
|
||||||
|
|||||||
@ -16,22 +16,21 @@ import ProductJobDialog from '@/components/product-dialog/job';
|
|||||||
import CompanyPublishJobBuy from '@/components/product-dialog/steps-ui/company-publish-job-buy';
|
import CompanyPublishJobBuy from '@/components/product-dialog/steps-ui/company-publish-job-buy';
|
||||||
import { EventName, PageUrl, RoleType } from '@/constants/app';
|
import { EventName, PageUrl, RoleType } from '@/constants/app';
|
||||||
import { CertificationStatusType } from '@/constants/company';
|
import { CertificationStatusType } from '@/constants/company';
|
||||||
import { CollectEventName, ReportEventId } from '@/constants/event';
|
import { ReportEventId } from '@/constants/event';
|
||||||
import { EMPLOY_TYPE_TITLE_MAP, GET_CONTACT_TYPE, JobManageStatus } from '@/constants/job';
|
import { EMPLOY_TYPE_TITLE_MAP, GET_CONTACT_TYPE, JobManageStatus } from '@/constants/job';
|
||||||
import { ProductType } from '@/constants/product';
|
import { ProductType } from '@/constants/product';
|
||||||
import useInviteCode from '@/hooks/use-invite-code';
|
import useInviteCode from '@/hooks/use-invite-code';
|
||||||
|
import { usePublishJob } from '@/hooks/use-publish-job';
|
||||||
import useUserInfo from '@/hooks/use-user-info';
|
import useUserInfo from '@/hooks/use-user-info';
|
||||||
import useRoleType from '@/hooks/user-role-type';
|
import useRoleType from '@/hooks/user-role-type';
|
||||||
import { RESPONSE_ERROR_CODE } from '@/http/constant';
|
import { RESPONSE_ERROR_CODE } from '@/http/constant';
|
||||||
import { HttpError } from '@/http/error';
|
import { HttpError } from '@/http/error';
|
||||||
import store from '@/store';
|
|
||||||
import { cacheJobId } from '@/store/actions';
|
|
||||||
import { JobDetails } from '@/types/job';
|
import { JobDetails } from '@/types/job';
|
||||||
import { IMaterialMessage } from '@/types/message';
|
import { IMaterialMessage } from '@/types/message';
|
||||||
import { switchRoleType } from '@/utils/app';
|
import { switchRoleType } from '@/utils/app';
|
||||||
import { copy, logWithPrefix } from '@/utils/common';
|
import { copy, logWithPrefix } from '@/utils/common';
|
||||||
import { collectEvent, reportEvent } from '@/utils/event';
|
import { reportEvent } from '@/utils/event';
|
||||||
import { getJobSalary, getJobTitle, postPublishJob, requestJobDetail } from '@/utils/job';
|
import { getJobSalary, getJobTitle, requestJobDetail } from '@/utils/job';
|
||||||
import { calcDistance, isValidLocation } from '@/utils/location';
|
import { calcDistance, isValidLocation } from '@/utils/location';
|
||||||
import { requestProfileDetail } from '@/utils/material';
|
import { requestProfileDetail } from '@/utils/material';
|
||||||
import { isChatWithSelf, postCreateChat } from '@/utils/message';
|
import { isChatWithSelf, postCreateChat } from '@/utils/message';
|
||||||
@ -176,44 +175,10 @@ const AnchorFooter = (props: { data: JobDetails }) => {
|
|||||||
|
|
||||||
const CompanyFooter = (props: { data: JobDetails }) => {
|
const CompanyFooter = (props: { data: JobDetails }) => {
|
||||||
const { data } = props;
|
const { data } = props;
|
||||||
const [showBuy, setShowBuy] = useState(false);
|
const [showBuy, setShowBuy, handlePublishJob] = usePublishJob(data.id);
|
||||||
const userInfo = useUserInfo();
|
|
||||||
|
|
||||||
const handleClickEdit = useCallback(() => navigateTo(PageUrl.JobPublish, { jobId: data.id }), [data]);
|
const handleClickEdit = useCallback(() => navigateTo(PageUrl.JobPublish, { jobId: data.id }), [data]);
|
||||||
|
|
||||||
const handlePublishJob = useCallback(async () => {
|
|
||||||
try {
|
|
||||||
if (userInfo.bossAuthStatus !== CertificationStatusType.Success) {
|
|
||||||
store.dispatch(cacheJobId(data.id));
|
|
||||||
navigateTo(PageUrl.CertificationStart);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Taro.showLoading();
|
|
||||||
await postPublishJob(data.id);
|
|
||||||
Taro.eventCenter.trigger(EventName.COMPANY_JOB_PUBLISH_CHANGED);
|
|
||||||
setShowBuy(false);
|
|
||||||
Toast.success('发布成功');
|
|
||||||
Taro.hideLoading();
|
|
||||||
} catch (error) {
|
|
||||||
Taro.hideLoading();
|
|
||||||
const e = error as HttpError;
|
|
||||||
const errorCode = e.errorCode;
|
|
||||||
const errorMsg = e.info?.() || e.message;
|
|
||||||
collectEvent(CollectEventName.PUBLISH_OPEN_JOB_FAILED, { jobId: data.id, error: e.info?.() || e.message });
|
|
||||||
if (errorCode === RESPONSE_ERROR_CODE.INSUFFICIENT_FREE_BALANCE) {
|
|
||||||
setShowBuy(true);
|
|
||||||
} else if (errorCode === RESPONSE_ERROR_CODE.INSUFFICIENT_BALANCE) {
|
|
||||||
Toast.info('您购买的产品已耗尽使用次数');
|
|
||||||
setShowBuy(true);
|
|
||||||
} else if (errorCode === RESPONSE_ERROR_CODE.BOSS_VIP_EXPIRED) {
|
|
||||||
Toast.info('该通告已到期,请创建新通告', 3000);
|
|
||||||
} else {
|
|
||||||
Toast.error(errorMsg || '发布失败请重试', 3000);
|
|
||||||
}
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
}, [data]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={`${PREFIX}__footer`}>
|
<div className={`${PREFIX}__footer`}>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Image } from '@tarojs/components';
|
// import { Image } from '@tarojs/components';
|
||||||
import Taro, { useLoad, useShareAppMessage } from '@tarojs/taro';
|
import Taro, { useLoad, useShareAppMessage } from '@tarojs/taro';
|
||||||
|
|
||||||
import { Button, Tabs } from '@taroify/core';
|
import { Button, Tabs } from '@taroify/core';
|
||||||
@ -12,29 +12,29 @@ import useInviteCode from '@/hooks/use-invite-code';
|
|||||||
import { switchRoleType } from '@/utils/app';
|
import { switchRoleType } from '@/utils/app';
|
||||||
import { openCustomerServiceChat } from '@/utils/common';
|
import { openCustomerServiceChat } from '@/utils/common';
|
||||||
import { getCurrentCityCode } from '@/utils/location';
|
import { getCurrentCityCode } from '@/utils/location';
|
||||||
import { getPageQuery, navigateTo } from '@/utils/route';
|
import { getPageQuery } from '@/utils/route';
|
||||||
import { getCommonShareMessage } from '@/utils/share';
|
import { getCommonShareMessage } from '@/utils/share';
|
||||||
import { checkCityCode } from '@/utils/user';
|
import { checkCityCode } from '@/utils/user';
|
||||||
|
|
||||||
import './index.less';
|
import './index.less';
|
||||||
|
|
||||||
const PREFIX = 'page-biz-service';
|
const PREFIX = 'page-biz-service';
|
||||||
const EXAMPLE_IMAGE = 'https://publiccdn.neighbourhood.com.cn/img/delegate-example.png';
|
// const EXAMPLE_IMAGE = 'https://publiccdn.neighbourhood.com.cn/img/delegate-example.png';
|
||||||
const COMMENT_IMAGE = 'https://publiccdn.neighbourhood.com.cn/img/delegate-comments.png';
|
// const COMMENT_IMAGE = 'https://publiccdn.neighbourhood.com.cn/img/delegate-comments.png';
|
||||||
export default function BizService() {
|
export default function BizService() {
|
||||||
const inviteCode = useInviteCode();
|
const inviteCode = useInviteCode();
|
||||||
const cityOperators = useCityOperators();
|
const cityOperators = useCityOperators();
|
||||||
const [value, setValue] = useState('0');
|
const [value, setValue] = useState('2');
|
||||||
|
|
||||||
const handleClickDelegate = useCallback(() => {
|
// const handleClickDelegate = useCallback(() => {
|
||||||
navigateTo(PageUrl.GroupDelegatePublish);
|
// navigateTo(PageUrl.GroupDelegatePublish);
|
||||||
}, []);
|
// }, []);
|
||||||
const handlePreview = (current: string) => {
|
// const handlePreview = (current: string) => {
|
||||||
Taro.previewImage({
|
// Taro.previewImage({
|
||||||
current,
|
// current,
|
||||||
urls: [EXAMPLE_IMAGE, COMMENT_IMAGE],
|
// urls: [EXAMPLE_IMAGE, COMMENT_IMAGE],
|
||||||
});
|
// });
|
||||||
};
|
// };
|
||||||
const handleOpenService = useCallback(() => {
|
const handleOpenService = useCallback(() => {
|
||||||
openCustomerServiceChat('https://work.weixin.qq.com/kfid/kfcd60708731367168d');
|
openCustomerServiceChat('https://work.weixin.qq.com/kfid/kfcd60708731367168d');
|
||||||
}, []);
|
}, []);
|
||||||
@ -80,35 +80,35 @@ export default function BizService() {
|
|||||||
<HomePage type={PageType.BatchPublish}>
|
<HomePage type={PageType.BatchPublish}>
|
||||||
<div className={PREFIX}>
|
<div className={PREFIX}>
|
||||||
<Tabs className={`${PREFIX}__tabs`} value={value} onChange={handleChange}>
|
<Tabs className={`${PREFIX}__tabs`} value={value} onChange={handleChange}>
|
||||||
<Tabs.TabPane value="0" title="群代发">
|
{/*<Tabs.TabPane value="0" title="群代发">*/}
|
||||||
<div className={`${PREFIX}__delegate`}>
|
{/* <div className={`${PREFIX}__delegate`}>*/}
|
||||||
<Image
|
{/* <Image*/}
|
||||||
mode="widthFix"
|
{/* mode="widthFix"*/}
|
||||||
className={`${PREFIX}__header-image`}
|
{/* className={`${PREFIX}__header-image`}*/}
|
||||||
src="https://publiccdn.neighbourhood.com.cn/img/pub-job.png"
|
{/* src="https://publiccdn.neighbourhood.com.cn/img/pub-job.png"*/}
|
||||||
/>
|
{/* />*/}
|
||||||
<div className={`${PREFIX}__delegate-h5`}>服务说明</div>
|
{/* <div className={`${PREFIX}__delegate-h5`}>服务说明</div>*/}
|
||||||
<div className={`${PREFIX}__delegate-card`}>
|
{/* <div className={`${PREFIX}__delegate-card`}>*/}
|
||||||
<div className={`${PREFIX}__delegate-body`}>服务方式:帮您把招聘需求发到众多同城合作主播群</div>
|
{/* <div className={`${PREFIX}__delegate-body`}>服务方式:帮您把招聘需求发到众多同城合作主播群</div>*/}
|
||||||
<div className={`${PREFIX}__delegate-body`}>群发次数:杭州、广州发3次,其他城市1次</div>
|
{/* <div className={`${PREFIX}__delegate-body`}>群发次数:杭州、广州发3次,其他城市1次</div>*/}
|
||||||
<div className={`${PREFIX}__delegate-body`}>内容要求:仅限带货主播招聘需求,其他不发</div>
|
{/* <div className={`${PREFIX}__delegate-body`}>内容要求:仅限带货主播招聘需求,其他不发</div>*/}
|
||||||
<div className={`${PREFIX}__delegate-body`}>主播联系:内容中留招聘方联系方式,主播直接联系</div>
|
{/* <div className={`${PREFIX}__delegate-body`}>主播联系:内容中留招聘方联系方式,主播直接联系</div>*/}
|
||||||
</div>
|
{/* </div>*/}
|
||||||
<div className={`${PREFIX}__delegate-h5`}>代发示例</div>
|
{/* <div className={`${PREFIX}__delegate-h5`}>代发示例</div>*/}
|
||||||
<div className={`${PREFIX}__delegate-card image`} onClick={() => handlePreview(EXAMPLE_IMAGE)}>
|
{/* <div className={`${PREFIX}__delegate-card image`} onClick={() => handlePreview(EXAMPLE_IMAGE)}>*/}
|
||||||
<Image className={`${PREFIX}__delegate-image`} src={EXAMPLE_IMAGE} mode="heightFix" />
|
{/* <Image className={`${PREFIX}__delegate-image`} src={EXAMPLE_IMAGE} mode="heightFix" />*/}
|
||||||
</div>
|
{/* </div>*/}
|
||||||
<div className={`${PREFIX}__delegate-h5`}>部分客户评价</div>
|
{/* <div className={`${PREFIX}__delegate-h5`}>部分客户评价</div>*/}
|
||||||
<div className={`${PREFIX}__delegate-card image`} onClick={() => handlePreview(COMMENT_IMAGE)}>
|
{/* <div className={`${PREFIX}__delegate-card image`} onClick={() => handlePreview(COMMENT_IMAGE)}>*/}
|
||||||
<Image className={`${PREFIX}__delegate-image`} src={COMMENT_IMAGE} mode="heightFix" />
|
{/* <Image className={`${PREFIX}__delegate-image`} src={COMMENT_IMAGE} mode="heightFix" />*/}
|
||||||
</div>
|
{/* </div>*/}
|
||||||
<div className={`${PREFIX}__delegate-fix`}>
|
{/* <div className={`${PREFIX}__delegate-fix`}>*/}
|
||||||
<Button className={`${PREFIX}__delegate-btn`} onClick={handleClickDelegate}>
|
{/* <Button className={`${PREFIX}__delegate-btn`} onClick={handleClickDelegate}>*/}
|
||||||
我要代发
|
{/* 我要代发*/}
|
||||||
</Button>
|
{/* </Button>*/}
|
||||||
</div>
|
{/* </div>*/}
|
||||||
</div>
|
{/* </div>*/}
|
||||||
</Tabs.TabPane>
|
{/*</Tabs.TabPane>*/}
|
||||||
<Tabs.TabPane
|
<Tabs.TabPane
|
||||||
value="1"
|
value="1"
|
||||||
title={
|
title={
|
||||||
|
|||||||
@ -88,4 +88,8 @@
|
|||||||
width: 76px;
|
width: 76px;
|
||||||
height: 81px;
|
height: 81px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.taroify-cell__right-icon {
|
||||||
|
line-height: 48px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,7 +51,7 @@ export type JobDetails = JobInfo &
|
|||||||
userId: string; // 发布人的 userId
|
userId: string; // 发布人的 userId
|
||||||
verifyFailReason?: string; // 审核不通过的原因
|
verifyFailReason?: string; // 审核不通过的原因
|
||||||
sourcePlat?: string;
|
sourcePlat?: string;
|
||||||
status: JobManageStatus
|
status: JobManageStatus;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface JobManageInfo {
|
export interface JobManageInfo {
|
||||||
|
|||||||
Reference in New Issue
Block a user