feat: first commit
This commit is contained in:
259
src/pages/material-view/index.tsx
Normal file
259
src/pages/material-view/index.tsx
Normal file
@ -0,0 +1,259 @@
|
||||
import { Button } from '@tarojs/components';
|
||||
import Taro, { useLoad, useShareAppMessage } from '@tarojs/taro';
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import CommonDialog from '@/components/common-dialog';
|
||||
import PageLoading from '@/components/page-loading';
|
||||
import SafeBottomPadding from '@/components/safe-bottom-padding';
|
||||
import { EventName, OpenSource, PageUrl } from '@/constants/app';
|
||||
import { CollectEventName } from '@/constants/event';
|
||||
import { MaterialViewSource } from '@/constants/material';
|
||||
import ProfileViewFragment from '@/fragments/profile/view';
|
||||
import { RESPONSE_ERROR_CODE } from '@/http/constant';
|
||||
import { HttpError } from '@/http/error';
|
||||
import { JobManageInfo } from '@/types/job';
|
||||
import { MaterialProfile } from '@/types/material';
|
||||
import { IJobMessage } from '@/types/message';
|
||||
import { copy } from '@/utils/common';
|
||||
import { collectEvent } from '@/utils/event';
|
||||
import { requestHasPublishedJob, requestJobDetail } from '@/utils/job';
|
||||
import { getMaterialShareMessage, requestReadProfile, requestShareProfile } from '@/utils/material';
|
||||
import { isChatWithSelf, postCreateChat } from '@/utils/message';
|
||||
import { getPageQuery, navigateBack, navigateTo, redirectTo } from '@/utils/route';
|
||||
import Toast from '@/utils/toast';
|
||||
|
||||
import './index.less';
|
||||
|
||||
const PREFIX = 'page-material-view';
|
||||
|
||||
interface IViewContext {
|
||||
resumeId: string;
|
||||
source: MaterialViewSource.AnchorList | MaterialViewSource.Chat;
|
||||
jobId?: string;
|
||||
}
|
||||
|
||||
interface IShareContext {
|
||||
resumeId: string;
|
||||
source: MaterialViewSource.Share;
|
||||
shareCode: string;
|
||||
}
|
||||
|
||||
const isShareContext = (context: IViewContext | IShareContext): context is IShareContext => {
|
||||
return !!(context as IShareContext).shareCode;
|
||||
};
|
||||
|
||||
const requestProfile = async (context: IViewContext | IShareContext) => {
|
||||
if (!context.resumeId) {
|
||||
throw new Error('参数错误');
|
||||
}
|
||||
if (isShareContext(context)) {
|
||||
const { resumeId, shareCode } = context;
|
||||
const profileDetail = await requestShareProfile({ resumeId, shareCode });
|
||||
return profileDetail;
|
||||
} else {
|
||||
const { resumeId, jobId } = context;
|
||||
const profileDetail = await requestReadProfile({ resumeId, jobId });
|
||||
return profileDetail;
|
||||
}
|
||||
};
|
||||
|
||||
export default function MaterialViewPage() {
|
||||
const [contactEnable, setContactEnable] = useState(true);
|
||||
const [profile, setProfile] = useState<MaterialProfile | null>(null);
|
||||
const [jobId, setJobId] = useState<string>();
|
||||
const [errorTips, setErrorTips] = useState<string>('');
|
||||
const [publishDialogVisible, setPublishDialogVisible] = useState(false);
|
||||
const [certificationDialogVisible, setCertificationDialogVisible] = useState(false);
|
||||
const [noTimeDialogVisible, setNoTimeDialogVisible] = useState(false);
|
||||
const [noVipLimitVisible, setNoVipLimitVisible] = useState(false);
|
||||
const [vipExpiredVisible, setVipExpiredVisible] = useState(false);
|
||||
|
||||
const onDev = useCallback(async () => profile && copy(profile.userId), [profile]);
|
||||
|
||||
const handleClickContact = useCallback(async () => {
|
||||
if (!profile) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (jobId) {
|
||||
const toUserId = profile.userId;
|
||||
if (isChatWithSelf(toUserId)) {
|
||||
Toast.error('不能与自己聊天');
|
||||
return;
|
||||
}
|
||||
const jobDetail = await requestJobDetail(jobId);
|
||||
const chat = await postCreateChat(toUserId);
|
||||
const jobMessage: IJobMessage = {
|
||||
id: jobDetail.id,
|
||||
title: jobDetail.title,
|
||||
employType: jobDetail.employType,
|
||||
salary: jobDetail.salary,
|
||||
lowPriceForFullTime: jobDetail.lowPriceForFullTime,
|
||||
highPriceForFullTime: jobDetail.highPriceForFullTime,
|
||||
lowPriceForPartyTime: jobDetail.lowPriceForPartyTime,
|
||||
highPriceForPartyTime: jobDetail.highPriceForPartyTime,
|
||||
};
|
||||
navigateTo(PageUrl.MessageChat, { chatId: chat.chatId, job: jobMessage, jobId });
|
||||
return;
|
||||
}
|
||||
if (!(await requestHasPublishedJob())) {
|
||||
setPublishDialogVisible(true);
|
||||
return;
|
||||
}
|
||||
navigateTo(PageUrl.JobSelectMyPublish, { source: OpenSource.MaterialViewPage });
|
||||
} catch (error) {
|
||||
const e = error as HttpError;
|
||||
const errorCode = e.errorCode;
|
||||
if (errorCode === RESPONSE_ERROR_CODE.INSUFFICIENT_BALANCE) {
|
||||
setErrorTips('今日10次开聊次数已用完,请明日再来');
|
||||
} else {
|
||||
Toast.error('请求失败请重试');
|
||||
}
|
||||
}
|
||||
}, [profile, jobId]);
|
||||
|
||||
const handleClickNoViewTimes = useCallback(() => {
|
||||
setNoTimeDialogVisible(false);
|
||||
navigateBack();
|
||||
}, []);
|
||||
|
||||
const handleClickGoPublish = useCallback(() => {
|
||||
setPublishDialogVisible(false);
|
||||
redirectTo(PageUrl.CertificationManage);
|
||||
}, []);
|
||||
|
||||
const handleClickGoCertification = useCallback(() => {
|
||||
setCertificationDialogVisible(false);
|
||||
redirectTo(PageUrl.CertificationStart);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const callback = (select: JobManageInfo, source: OpenSource) =>
|
||||
source === OpenSource.MaterialViewPage && setJobId(select.id);
|
||||
Taro.eventCenter.on(EventName.SELECT_MY_PUBLISH_JOB, callback);
|
||||
return () => {
|
||||
Taro.eventCenter.off(EventName.SELECT_MY_PUBLISH_JOB, callback);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useLoad(async () => {
|
||||
const context = getPageQuery<IViewContext | IShareContext>();
|
||||
try {
|
||||
const profileDetail = await requestProfile(context);
|
||||
setProfile(profileDetail);
|
||||
if (!isShareContext(context)) {
|
||||
setJobId(context.jobId);
|
||||
Taro.eventCenter.trigger(EventName.VIEW_MATERIAL_SUCCESS, profileDetail.id);
|
||||
}
|
||||
if (context.source === MaterialViewSource.Chat) {
|
||||
setContactEnable(false);
|
||||
}
|
||||
Taro.setNavigationBarTitle({ title: profileDetail.name || '主播模卡' });
|
||||
} catch (error) {
|
||||
const e = error as HttpError;
|
||||
const errorCode = e.errorCode;
|
||||
collectEvent(CollectEventName.VIEW_MATERIAL_FAILED, { context, error: e.info?.() || e.message });
|
||||
console.error(e);
|
||||
if (errorCode === RESPONSE_ERROR_CODE.BOSS_NOT_AUTH) {
|
||||
setCertificationDialogVisible(true);
|
||||
} else if (errorCode === RESPONSE_ERROR_CODE.NO_PUBLISHED_JOB) {
|
||||
setPublishDialogVisible(true);
|
||||
} else if (errorCode === RESPONSE_ERROR_CODE.INSUFFICIENT_BALANCE) {
|
||||
setNoTimeDialogVisible(true);
|
||||
} else if (errorCode === RESPONSE_ERROR_CODE.INSUFFICIENT_FREE_BALANCE) {
|
||||
setNoVipLimitVisible(true);
|
||||
} else if (errorCode === RESPONSE_ERROR_CODE.BOSS_VIP_EXPIRED) {
|
||||
setVipExpiredVisible(true);
|
||||
} else {
|
||||
Toast.error(e.message || '加载失败');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
useShareAppMessage(async () => {
|
||||
const shareMessage = await getMaterialShareMessage(profile);
|
||||
return shareMessage as BL.Anything;
|
||||
});
|
||||
|
||||
if (!profile) {
|
||||
return (
|
||||
<>
|
||||
<PageLoading />
|
||||
<CommonDialog
|
||||
content="要查看主播详情,请先完成实人认证"
|
||||
confirm="去认证"
|
||||
visible={certificationDialogVisible}
|
||||
onClose={() => setCertificationDialogVisible(false)}
|
||||
onClick={handleClickGoCertification}
|
||||
/>
|
||||
<CommonDialog
|
||||
content="请先发布一个认证通告"
|
||||
confirm="去发布"
|
||||
visible={publishDialogVisible}
|
||||
onClose={() => setPublishDialogVisible(false)}
|
||||
onClick={handleClickGoPublish}
|
||||
/>
|
||||
<CommonDialog
|
||||
content="请先发布一个认证通告"
|
||||
confirm="去发布"
|
||||
visible={noVipLimitVisible}
|
||||
onClose={() => setNoVipLimitVisible(false)}
|
||||
onClick={handleClickGoPublish}
|
||||
>
|
||||
<div className={`${PREFIX}__no-time-tips`}>免费查看模卡详情次数已用完</div>
|
||||
</CommonDialog>
|
||||
<CommonDialog
|
||||
content="请先发布一个认证通告"
|
||||
confirm="去发布"
|
||||
visible={vipExpiredVisible}
|
||||
onClose={() => setVipExpiredVisible(false)}
|
||||
onClick={handleClickGoPublish}
|
||||
/>
|
||||
<CommonDialog
|
||||
content="今日查看模卡详情次数已用完"
|
||||
confirm="确定"
|
||||
visible={noTimeDialogVisible}
|
||||
onClick={handleClickNoViewTimes}
|
||||
>
|
||||
<div className={`${PREFIX}__no-time-tips`}> 当前每个通告单日查看次数为 20 次</div>
|
||||
</CommonDialog>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={PREFIX}>
|
||||
<ProfileViewFragment profile={profile} editable={false} onDev={onDev} />
|
||||
<div className={`${PREFIX}__footer`}>
|
||||
<div className={`${PREFIX}__footer__buttons`}>
|
||||
<Button className={`${PREFIX}__footer__buttons__share`} openType="share">
|
||||
分享
|
||||
</Button>
|
||||
{contactEnable && (
|
||||
<Button className={`${PREFIX}__footer__buttons__contact`} onClick={handleClickContact}>
|
||||
立即联系
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<SafeBottomPadding />
|
||||
</div>
|
||||
<div>
|
||||
<CommonDialog
|
||||
content="请先发布一个认证通告"
|
||||
confirm="去发布"
|
||||
visible={publishDialogVisible}
|
||||
onClose={() => setPublishDialogVisible(false)}
|
||||
onClick={handleClickGoPublish}
|
||||
/>
|
||||
<CommonDialog
|
||||
content={errorTips}
|
||||
confirm="确定"
|
||||
visible={!!errorTips}
|
||||
onClose={() => setErrorTips('')}
|
||||
onClick={() => setErrorTips('')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user