feat: first commit

This commit is contained in:
eleanor.mao
2025-03-31 22:34:22 +08:00
commit d25187c9c8
390 changed files with 57031 additions and 0 deletions

View File

@ -0,0 +1,17 @@
@import '@/styles/variables.less';
.user-job-list {
&__list-date-group {
height: 72px;
font-size: 24px;
line-height: 72px;
padding: 0 24px;
color: @blColor;
}
&__list-card {
&.last {
margin-bottom: 0;
}
}
}

View File

@ -0,0 +1,165 @@
import { List, PullRefresh } from '@taroify/core';
import classNames from 'classnames';
import { useCallback, useEffect, useRef, useState } from 'react';
import JobCard from '@/components/job-card';
import ListPlaceholder from '@/components/list-placeholder';
import { UserJobType } from '@/constants/job';
import { JobInfo, GetUserJobRequest } from '@/types/job';
import { logWithPrefix } from '@/utils/common';
import { requestUserJobList as requestData } from '@/utils/job';
import './index.less';
interface IRequestProps extends Partial<GetUserJobRequest> {
type: number;
}
export interface IJobListProps extends IRequestProps {
refreshDisabled?: boolean;
listHeight?: number;
className?: string;
}
const FIRST_PAGE = 0;
const PAGE_SIZE = 40;
const PREFIX = 'user-job-list';
const log = logWithPrefix(PREFIX);
function UserJobList(props: IJobListProps) {
const { className, listHeight, refreshDisabled, type = UserJobType.MyDeclared, keyWord } = props;
const [refreshing, setRefreshing] = useState(false);
const [hasMore, setHasMore] = useState(true);
const [loadingMore, setLoadingMore] = useState(false);
const [loadMoreError, setLoadMoreError] = useState(false);
const [dataMap, setDataMap] = useState<Map<string, JobInfo[]>>(new Map());
const currentPage = useRef<number>(FIRST_PAGE);
const requestProps = useRef<IRequestProps>({ type });
const dateGroups = [...dataMap.keys()].sort().reverse();
const handleRefresh = useCallback(async () => {
log('start pull refresh');
try {
setRefreshing(true);
setLoadMoreError(false);
const { page, hasMore: more, dataMap: map } = await requestData({ ...requestProps.current, page: 1 });
setHasMore(more);
setDataMap(map);
currentPage.current = page;
log('pull refresh success');
} catch (e) {
setDataMap(new Map());
setHasMore(false);
setLoadMoreError(true);
currentPage.current = FIRST_PAGE;
log('pull refresh failed');
} finally {
setRefreshing(false);
}
}, []);
const handleLoadMore = useCallback(async () => {
log('start load more', hasMore);
if (!hasMore) {
return;
}
setLoadMoreError(false);
setLoadingMore(true);
try {
const {
page,
hasMore: more,
dataMap: map,
} = await requestData({ ...requestProps.current, page: currentPage.current + 1 });
const newMap = new Map(dataMap);
for (const date of map.keys()) {
const newJobs = map.get(date) || [];
if (newMap.has(date)) {
const jobs = newMap.get(date);
jobs?.push(...newJobs);
} else {
newMap.set(date, newJobs);
}
}
setDataMap(newMap);
setHasMore(more);
currentPage.current = page;
log('load more success');
} catch (e) {
setLoadMoreError(true);
log('load more failed');
} finally {
setLoadingMore(false);
}
}, [dataMap, currentPage, hasMore]);
useEffect(() => {
log('request params changed');
requestProps.current = { type, keyWord, pageSize: PAGE_SIZE };
}, [type, keyWord]);
// 初始化数据&配置变更后刷新数据
useEffect(() => {
const refresh = async () => {
log('props changed, start refresh list data');
try {
setDataMap(new Map());
setLoadingMore(true);
setLoadMoreError(false);
const { page, hasMore: more, dataMap: map } = await requestData({ ...requestProps.current, page: 1 });
setHasMore(more);
setDataMap(map);
currentPage.current = page;
} catch (e) {
setDataMap(new Map());
setHasMore(false);
setLoadMoreError(true);
currentPage.current = FIRST_PAGE;
} finally {
log('props changed, refresh list data end');
setLoadingMore(false);
}
};
refresh();
}, [type, keyWord]);
return (
<PullRefresh
className={classNames(`${PREFIX}__pull-refresh`, className)}
loading={refreshing}
onRefresh={handleRefresh}
disabled={refreshDisabled}
>
<List
hasMore={hasMore}
onLoad={handleLoadMore}
loading={loadingMore || refreshing}
disabled={loadMoreError}
fixedHeight={typeof listHeight !== 'undefined'}
style={listHeight ? { height: `${listHeight}px` } : undefined}
>
{dateGroups.map(date => {
const jobs = dataMap.get(date) || [];
return (
<>
<div className={`${PREFIX}__list-date-group`} key={date}>
{date}
</div>
{jobs.map((item, index) => (
<JobCard
data={item}
key={item.id}
className={classNames(`${PREFIX}__list-card`, { last: index === jobs.length - 1 })}
/>
))}
</>
);
})}
<ListPlaceholder hasMore={hasMore} loadingMore={loadingMore} loadMoreError={loadMoreError} />
</List>
</PullRefresh>
);
}
export default UserJobList;