boluo-app-main/src/pages/job/index.tsx
魔力叉烧包 5acc25c8c9 feat: login
2025-06-08 22:57:23 +08:00

156 lines
5.1 KiB
TypeScript

import Taro, { useDidShow, useLoad, useShareAppMessage } from '@tarojs/taro';
import { Tabs } from '@taroify/core';
import { useCallback, useEffect, useRef, useState } from 'react';
import HomePage from '@/components/home-page';
import { LoginGuide } from '@/components/login-guide';
import MaterialGuide from '@/components/material-guide';
import { EventName, OpenSource, PageUrl } from '@/constants/app';
import { EmployType, JOB_PAGE_TABS, SortType } from '@/constants/job';
import JobFragment from '@/fragments/job/base';
import useInviteCode from '@/hooks/use-invite-code';
import useLocation from '@/hooks/use-location';
import useNavigation from '@/hooks/use-navigation';
import { Coordinate } from '@/types/location';
import { logWithPrefix } from '@/utils/common';
import { getWxLocation, isNotNeedAuthorizeLocation, requestLocation } from '@/utils/location';
import { requestUnreadMessageCount } from '@/utils/message';
import { getInviteCodeFromQueryAndUpdate } from '@/utils/partner';
import { getJumpUrl, getPageQuery, navigateTo } from '@/utils/route';
import { getCommonShareMessage } from '@/utils/share';
import Toast from '@/utils/toast';
import { isNeedCreateMaterial } from '@/utils/user';
import './index.less';
const PREFIX = 'job';
const log = logWithPrefix(PREFIX);
export default function Job() {
const location = useLocation();
const { barHeight, statusBarHeight } = useNavigation();
const inviteCode = useInviteCode();
const [tabType, setTabType] = useState<EmployType>(EmployType.All);
const [sortType, setSortType] = useState<SortType>(SortType.RECOMMEND);
const [cityCode, setCityCode] = useState<string>(location.cityCode);
const [coordinate, setCoordinate] = useState<Coordinate>({
latitude: location.latitude,
longitude: location.longitude,
});
const [showMaterialGuide, setShowMaterialGuide] = useState(false);
const [showAuthorize, setShowAuthorize] = useState(false);
const cityValuesChangedRef = useRef(false);
const handleTypeChange = useCallback(value => setTabType(value), []);
const handleClickCity = useCallback(
() => navigateTo(PageUrl.CitySearch, { city: cityCode, source: OpenSource.JobPage }),
[cityCode]
);
const handleClickSortType = useCallback(
async (type: SortType) => {
if (type === SortType.DISTANCE && (!location.latitude || !location.longitude)) {
const res = await getWxLocation();
if (!res) {
Toast.info('获取位置信息失败,请重试');
return;
}
const { latitude, longitude } = res;
setCoordinate({ latitude, longitude });
}
setSortType(type);
},
[location]
);
const handleCityChange = useCallback(data => {
log('handleCityChange', data);
const { openSource, cityCode: code } = data;
if (openSource !== OpenSource.JobPage) {
return;
}
cityValuesChangedRef.current = true;
setCityCode(code);
}, []);
const handleAfterBindPhone = useCallback(async () => {
if (await isNeedCreateMaterial()) {
setShowMaterialGuide(true);
}
}, []);
useEffect(() => {
Taro.eventCenter.on(EventName.SELECT_CITY, handleCityChange);
return () => {
Taro.eventCenter.off(EventName.SELECT_CITY, handleCityChange);
};
}, [handleCityChange]);
useEffect(() => {
if (cityValuesChangedRef.current) {
return;
}
setCityCode(location.cityCode);
}, [location]);
useLoad(async () => {
const query = getPageQuery<{ sortType: SortType; c?: string; scene?: string }>();
const type = query.sortType;
if (type === SortType.CREATE_TIME) {
setSortType(type);
}
getInviteCodeFromQueryAndUpdate(query);
if (await isNotNeedAuthorizeLocation()) {
log('not need authorize location');
requestLocation();
} else {
log('show authorize location dialog');
setShowAuthorize(true);
requestLocation(true);
}
});
useDidShow(() => requestUnreadMessageCount());
useShareAppMessage(() => {
if (sortType === SortType.CREATE_TIME) {
return {
title: '这里有今日全城新增通告,快来看看',
path: getJumpUrl(PageUrl.Job, { sortType, c: inviteCode }),
};
}
return getCommonShareMessage(true, inviteCode);
});
return (
<HomePage>
<Tabs
swipeable
value={tabType}
className={`${PREFIX}__tabs`}
onChange={handleTypeChange}
style={{ height: barHeight.current, paddingTop: statusBarHeight.current }}
>
{JOB_PAGE_TABS.map(tab => (
<Tabs.TabPane value={tab.type} title={tab.title} key={tab.type}>
<JobFragment
cityCode={cityCode}
sortType={sortType}
employType={tab.type}
coordinate={coordinate}
onClickCity={handleClickCity}
onClickSort={handleClickSortType}
/>
</Tabs.TabPane>
))}
</Tabs>
<div>
<LoginGuide disabled={showAuthorize} onAfterBind={handleAfterBindPhone} />
{showMaterialGuide && <MaterialGuide onClose={() => setShowMaterialGuide(false)} />}
</div>
</HomePage>
);
}