feat:
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
@import '@/styles/common.less';
|
||||
@import '@/styles/variables.less';
|
||||
|
||||
|
||||
.job-card {
|
||||
&__container {
|
||||
width: 100%;
|
||||
@ -11,6 +11,16 @@
|
||||
border-radius: 16px;
|
||||
background: #FFFFFF;
|
||||
margin-bottom: 24px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&__mask {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
&__header {
|
||||
@ -160,4 +170,4 @@
|
||||
color: @blColorG2;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,13 +5,13 @@ import React, { useCallback } from 'react';
|
||||
|
||||
import { CertificationStatusIcon } from '@/components/certification-status';
|
||||
import { PageUrl } from '@/constants/app';
|
||||
import { CITY_CODE_TO_NAME_MAP, COUNTY_CODE_TO_NAME_MAP } from '@/constants/city';
|
||||
// import { CITY_CODE_TO_NAME_MAP, COUNTY_CODE_TO_NAME_MAP } from '@/constants/city';
|
||||
import { CertificationStatusType } from '@/constants/company';
|
||||
import { EMPLOY_TYPE_TITLE_MAP, EmployType } from '@/constants/job';
|
||||
import { JobInfo } from '@/types/job';
|
||||
import { LocationInfo } from '@/types/location';
|
||||
// import { LocationInfo } from '@/types/location';
|
||||
import { getJobSalary, getJobTitle } from '@/utils/job';
|
||||
import { calcDistance } from '@/utils/location';
|
||||
// import { calcDistance } from '@/utils/location';
|
||||
import { navigateTo, redirectTo } from '@/utils/route';
|
||||
|
||||
import './index.less';
|
||||
@ -23,16 +23,16 @@ interface IProps {
|
||||
}
|
||||
|
||||
const PREFIX = 'job-card';
|
||||
const getCityDes = (location: LocationInfo) => {
|
||||
if (!location) {
|
||||
return '';
|
||||
}
|
||||
let des = CITY_CODE_TO_NAME_MAP.get(location.cityCode);
|
||||
if (location.countyCode) {
|
||||
des += `-${COUNTY_CODE_TO_NAME_MAP.get(location.countyCode)}`;
|
||||
}
|
||||
return des;
|
||||
};
|
||||
// const getCityDes = (location: LocationInfo) => {
|
||||
// if (!location) {
|
||||
// return '';
|
||||
// }
|
||||
// let des = CITY_CODE_TO_NAME_MAP.get(location.cityCode);
|
||||
// if (location.countyCode) {
|
||||
// des += `-${COUNTY_CODE_TO_NAME_MAP.get(location.countyCode)}`;
|
||||
// }
|
||||
// return des;
|
||||
// };
|
||||
|
||||
function JobCard(props: IProps) {
|
||||
const { className, data, redirectOpen } = props;
|
||||
@ -45,7 +45,7 @@ function JobCard(props: IProps) {
|
||||
publisher,
|
||||
publisherAvatar,
|
||||
jobLocation,
|
||||
distance,
|
||||
// distance,
|
||||
isAuthed = false,
|
||||
} = data;
|
||||
|
||||
@ -104,6 +104,7 @@ function JobCard(props: IProps) {
|
||||
</div>
|
||||
{/*<div className={`${PREFIX}__city`}>{getCityDes(jobLocation)}</div>*/}
|
||||
</div>
|
||||
{data.isRead && <div className={`${PREFIX}__mask`} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import Taro from '@tarojs/taro';
|
||||
|
||||
import { List, PullRefresh } from '@taroify/core';
|
||||
import classNames from 'classnames';
|
||||
import { isEqual } from 'lodash-es';
|
||||
@ -5,6 +7,7 @@ import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import JobCard from '@/components/job-card';
|
||||
import ListPlaceholder from '@/components/list-placeholder';
|
||||
import { EventName } from '@/constants/app';
|
||||
import { JobType, EmployType, SortType } from '@/constants/job';
|
||||
import { JobInfo, GetJobsRequest } from '@/types/job';
|
||||
import { logWithPrefix } from '@/utils/common';
|
||||
@ -58,6 +61,23 @@ function JobList(props: IJobListProps) {
|
||||
const prevRequestProps = useRef<IRequestProps>({});
|
||||
const onListEmptyRef = useRef(onListEmpty);
|
||||
|
||||
const handleReadJob = useCallback(
|
||||
(jobId: string) => {
|
||||
const index = dataList.findIndex(d => String(d.id) === jobId);
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
const job = dataList[index];
|
||||
if (!job || job.isRead) {
|
||||
return;
|
||||
}
|
||||
log('auto mark read', jobId);
|
||||
dataList.splice(index, 1, { ...job, isRead: true });
|
||||
setDataList([...dataList]);
|
||||
},
|
||||
[dataList]
|
||||
);
|
||||
|
||||
const handleRefresh = useCallback(async () => {
|
||||
log('start pull refresh');
|
||||
try {
|
||||
@ -109,6 +129,13 @@ function JobList(props: IJobListProps) {
|
||||
onListEmptyRef.current = onListEmpty;
|
||||
}, [onListEmpty]);
|
||||
|
||||
useEffect(() => {
|
||||
Taro.eventCenter.on(EventName.VIEW_JOB_SUCCESS, handleReadJob);
|
||||
return () => {
|
||||
Taro.eventCenter.off(EventName.VIEW_JOB_SUCCESS, handleReadJob);
|
||||
};
|
||||
}, [handleReadJob]);
|
||||
|
||||
useEffect(() => {
|
||||
log('request params changed');
|
||||
requestProps.current = {
|
||||
|
||||
@ -39,9 +39,7 @@ function JoinEntry({ onBindSuccess }: JoinEntryProps) {
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
{visible && (
|
||||
<LoginDialog disableCheck onCancel={() => setVisible(false)} onSuccess={onBindSuccess} needPhone={needPhone} />
|
||||
)}
|
||||
{visible && <LoginDialog onCancel={() => setVisible(false)} onSuccess={onBindSuccess} needPhone={needPhone} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@ -8,7 +8,51 @@
|
||||
background: #6d3df5;
|
||||
color: #fff;
|
||||
|
||||
&__simple {
|
||||
&-simple {
|
||||
padding: 39px 35px;
|
||||
height: 120px;
|
||||
box-sizing: border-box;
|
||||
&__bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
border-radius: 16px;
|
||||
height: 100%;
|
||||
}
|
||||
&__content {
|
||||
.flex-row();
|
||||
line-height: 42px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 26px;
|
||||
color: #FFFFFF;
|
||||
|
||||
|
||||
}
|
||||
|
||||
&__money {
|
||||
font-weight: 800;
|
||||
margin-left: 12px;
|
||||
font-size: 44px;
|
||||
}
|
||||
&__button {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: 44px;
|
||||
right: 24px;
|
||||
font-size: 28px;
|
||||
line-height: 32px;
|
||||
&-image {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__bg {
|
||||
@ -28,20 +72,7 @@
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&__button {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: 44px;
|
||||
right: 56px;
|
||||
font-size: 24px;
|
||||
line-height: 24px;
|
||||
&-image {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-block;
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
|
||||
@ -144,24 +144,37 @@ export default function PartnerKanban({ simple }: PartnerKanbanProps) {
|
||||
useEffect(() => {
|
||||
getProfitStats();
|
||||
}, []);
|
||||
if (simple) {
|
||||
return (
|
||||
<div className={`${PREFIX} ${PREFIX}-simple`}>
|
||||
<Image
|
||||
className={`${PREFIX}-simple__bg`}
|
||||
src="https://publiccdn.neighbourhood.com.cn/img/partner_bg.png"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<div className={`${PREFIX}-simple__content`}>
|
||||
<div className={`${PREFIX}-simple__title`}>总收益(元)</div>
|
||||
<div className={`${PREFIX}-simple__money`}>{formatMoney(total)}</div>
|
||||
</div>
|
||||
<div className={`${PREFIX}-simple__button`} onClick={handleNavigate}>
|
||||
详情
|
||||
<Image
|
||||
className={`${PREFIX}-simple__button-image`}
|
||||
mode="aspectFit"
|
||||
src={require('@/statics/svg/caret-right.svg')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className={`${PREFIX} ${simple ? `${PREFIX}__simple` : ''}`}>
|
||||
<div className={PREFIX}>
|
||||
<Image
|
||||
className={`${PREFIX}__bg`}
|
||||
src="https://publiccdn.neighbourhood.com.cn/img/partner_bg.png"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<div className={`${PREFIX}__content`}>
|
||||
{simple && (
|
||||
<div className={`${PREFIX}__button`} onClick={handleNavigate}>
|
||||
查看详情
|
||||
<Image
|
||||
className={`${PREFIX}__button-image`}
|
||||
mode="aspectFit"
|
||||
src={require('@/statics/svg/caret-right.svg')}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className={`${PREFIX}__total`}>
|
||||
<div className={`${PREFIX}__title`}>总收益(元)</div>
|
||||
<div className={`${PREFIX}__money`}>{formatMoney(total)}</div>
|
||||
@ -183,25 +196,21 @@ export default function PartnerKanban({ simple }: PartnerKanbanProps) {
|
||||
<div className={`${PREFIX}__money`}>{formatMoney(stats.availableProfit)}</div>
|
||||
</div>
|
||||
</div>
|
||||
{!simple && (
|
||||
<div className={`${PREFIX}__buttons`}>
|
||||
<Button className={`${PREFIX}__withdraw`} onClick={handleViewWithdraw}>
|
||||
提现
|
||||
</Button>
|
||||
<Button className={`${PREFIX}__record`} onClick={handleNavigateRecord}>
|
||||
提现记录
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
<div className={`${PREFIX}__buttons`}>
|
||||
<Button className={`${PREFIX}__withdraw`} onClick={handleViewWithdraw}>
|
||||
提现
|
||||
</Button>
|
||||
<Button className={`${PREFIX}__record`} onClick={handleNavigateRecord}>
|
||||
提现记录
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
{!simple && <TipDialog open={tipOpen} onClose={handleTipClose} />}
|
||||
{!simple && (
|
||||
<WithdrawDialog
|
||||
count={Math.min(Number(formatMoney(stats.availableBalance)), 200)}
|
||||
open={withdrawOpen}
|
||||
onClose={handleWithdrawClose}
|
||||
/>
|
||||
)}
|
||||
<TipDialog open={tipOpen} onClose={handleTipClose} />
|
||||
<WithdrawDialog
|
||||
count={Math.min(Number(formatMoney(stats.availableBalance)), 200)}
|
||||
open={withdrawOpen}
|
||||
onClose={handleWithdrawClose}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ export enum EventName {
|
||||
SELECT_MY_PUBLISH_JOB = 'select_my_publish_job',
|
||||
EXIT_CHAT_PAGE = 'exit_chat_page',
|
||||
VIEW_MATERIAL_SUCCESS = 'view_material_success',
|
||||
VIEW_JOB_SUCCESS = 'view_job_success',
|
||||
}
|
||||
|
||||
export enum OpenSource {
|
||||
|
||||
@ -18,7 +18,8 @@ import {
|
||||
ALL_SORT_TYPES,
|
||||
EMPLOY_TYPE_TITLE_MAP,
|
||||
EmployType,
|
||||
JOB_TABS, JobSourceType,
|
||||
JOB_TABS,
|
||||
JobSourceType,
|
||||
JobType,
|
||||
SORT_TYPE_TITLE_MAP,
|
||||
SortType,
|
||||
@ -143,12 +144,7 @@ function JobFragment(props: IProps) {
|
||||
return (
|
||||
<div className={`${PREFIX}__container`}>
|
||||
<div className={`${PREFIX}__top-search-bar`}>
|
||||
<SearchInput
|
||||
disabled
|
||||
className={`${PREFIX}__search`}
|
||||
placeholder="试试 女装"
|
||||
onClick={handleClickSearch}
|
||||
/>
|
||||
<SearchInput disabled className={`${PREFIX}__search`} placeholder="试试 女装" onClick={handleClickSearch} />
|
||||
<div className={classNames(`${PREFIX}__employType-select`)} onClick={handleClickEmployTypeSelect}>
|
||||
<div className="title">
|
||||
{employType && employType !== EmployType.All ? EMPLOY_TYPE_TITLE_MAP[employType] : '类型'}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
// export const DOMAIN = 'http://192.168.60.191:8082';
|
||||
export const DOMAIN = process.env.BRAND === 'dev' ? 'https://dev.neighbourhood.cn' : 'https://neighbourhood.cn';
|
||||
// export const DOMAIN = 'https://dev.neighbourhood.cn';
|
||||
export const BASE_URL = `${DOMAIN}/api`;
|
||||
|
||||
export enum API {
|
||||
|
||||
@ -286,6 +286,7 @@ export default function JobDetail() {
|
||||
if (!jobId) {
|
||||
return;
|
||||
}
|
||||
Taro.eventCenter.trigger(EventName.VIEW_JOB_SUCCESS, jobId);
|
||||
try {
|
||||
const res = await requestJobDetail(jobId);
|
||||
setData(res);
|
||||
|
||||
@ -17,6 +17,7 @@ export interface JobInfo {
|
||||
distance?: number; // 距离。一期没有
|
||||
isAuthed?: boolean; // 是否认证
|
||||
companyName?: string;
|
||||
isRead?: boolean;
|
||||
}
|
||||
|
||||
export interface CreateJobInfo extends Pick<JobInfo, 'title' | 'employType' | 'jobDescription'> {
|
||||
|
||||
Reference in New Issue
Block a user