feat: 代招代发

This commit is contained in:
chashaobao
2025-11-06 00:06:03 +08:00
parent 5e3e6903cb
commit 4d146fb1e4
14 changed files with 300 additions and 162 deletions

View File

@ -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;
}
}
}

View File

@ -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>
); );

View File

@ -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;
}
} }

View File

@ -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>
); );

View File

@ -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) => (

View File

@ -48,7 +48,7 @@ const CompanyTabs: TabItemType[] = [
{ {
type: PageType.BatchPublish, type: PageType.BatchPublish,
pagePath: PageUrl.UserBatchPublish, pagePath: PageUrl.UserBatchPublish,
text: '代招代发', text: '代招',
}, },
]; ];

View 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];
};

View File

@ -1,3 +1,3 @@
export default definePageConfig({ export default definePageConfig({
navigationBarTitleText: '群代发', navigationBarTitleText: '加速招聘',
}); });

View File

@ -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>
); );
} }

View File

@ -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>

View File

@ -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`}>

View File

@ -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`}>广31</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={

View File

@ -88,4 +88,8 @@
width: 76px; width: 76px;
height: 81px; height: 81px;
} }
.taroify-cell__right-icon {
line-height: 48px;
}
} }

View File

@ -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 {