diff --git a/src/app.tsx b/src/app.tsx index 903ca06..da271d6 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -6,7 +6,7 @@ import { Provider } from 'react-redux'; import { REFRESH_UNREAD_COUNT_TIME } from '@/constants/message'; import http from '@/http'; import store from '@/store'; -import { requestCityOperators } from '@/utils/location'; +import { requestCityConfigs } from '@/utils/location'; import { requestUnreadMessageCount } from '@/utils/message'; import { decryptOpenGid, getInviteCode, getInviteCodeFromQuery } from '@/utils/partner'; import qiniuUpload from '@/utils/qiniu-upload'; @@ -30,7 +30,7 @@ function App({ children }: PropsWithChildren) { }); useDidShow(options => { - requestCityOperators(); + requestCityConfigs(); console.log(options); const inviteCode = getInviteCodeFromQuery(options?.query || {}); @@ -48,7 +48,7 @@ function App({ children }: PropsWithChildren) { // @ts-expect-error encryptedData: info.encryptedData, }); - console.log('哈哈哈', info); + console.log('getGroupEnterInfo', info); }) .catch(() => { console.log('没有解析到群', options?.scene); diff --git a/src/components/bl-checkbox/index.less b/src/components/bl-checkbox/index.less index 12c8c53..7d044c3 100644 --- a/src/components/bl-checkbox/index.less +++ b/src/components/bl-checkbox/index.less @@ -2,20 +2,36 @@ @import '@/styles/variables.less'; .profile-checkbox { - &__group { width: 100%; height: 100%; .flex-row(); + flex-wrap: wrap; + gap: 24px; } &__item { - flex: 1; - height: 100%; - } + flex: 0 1 auto; + padding: 34px 36px; + line-height: 32px; + border-radius: 16px; + border: 2px solid #fff; + background: #fff; + margin-right: 0; + margin-bottom: 0; + box-sizing: border-box; + &.active { + background: rgba(109, 61, 245, 0.12); + border: 2px solid #6d3df5; - &__icon { - width: 36px; - height: 36px; + .taroify-checkbox__label { + color: #6d3df5; + } + } + + .taroify-checkbox__label { + line-height: 32px; + margin-left: 0; + } } -} \ No newline at end of file +} diff --git a/src/components/bl-checkbox/index.tsx b/src/components/bl-checkbox/index.tsx index 3417585..ff0cb7e 100644 --- a/src/components/bl-checkbox/index.tsx +++ b/src/components/bl-checkbox/index.tsx @@ -1,42 +1,44 @@ -import { Image } from '@tarojs/components'; - import { Checkbox } from '@taroify/core'; import { CheckboxProps, CheckboxGroupProps } from '@taroify/core/checkbox'; +import CheckboxGroupContext from '@taroify/core/checkbox/checkbox-group.context'; +import { useContext } from 'react'; import './index.less'; interface IProps extends CheckboxProps { text: string; +} + +interface IGroupProps extends CheckboxGroupProps { value: BL.Anything[]; } -interface IGroupProps extends CheckboxGroupProps {} - const PREFIX = 'profile-checkbox'; -export function BlCheckboxGroup(props: IGroupProps) { - return ; +export function BlCheckboxGroup({ value, onChange, children }: IGroupProps) { + return ( + + {children} + + ); } export function BlCheckbox(props: IProps) { - const { name, text, value } = props; + const { name, text } = props; + const { value: names = [], onChange: onNamesChange } = useContext(CheckboxGroupContext); + const checked = names.includes(name); + const handleClick = () => { + if (!name) return; + + if (checked) { + onNamesChange?.(names.filter(aName => aName !== name)); + } else { + onNamesChange?.([...names, name]); + } + }; return ( - - } - > + {text} ); diff --git a/src/components/partner-intro/index.less b/src/components/partner-intro/index.less index 47820d6..088d8af 100644 --- a/src/components/partner-intro/index.less +++ b/src/components/partner-intro/index.less @@ -36,7 +36,7 @@ padding-right: 9px; font-size: 64px; line-height: 62px; - background: linear-gradient(87.53deg, #683DE3 0.4%, #39227D 84.55%); + background: linear-gradient(87.53deg, #683de3 0.4%, #39227d 84.55%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -87,31 +87,48 @@ box-sizing: border-box; height: 130px; padding: 24px 32px; - &-time { + &-top-line { + .flex-row(); font-style: normal; font-size: 28px; line-height: 40px; color: #333333; font-weight: 400; position: relative; + .noWrap(); + } + &-id { + .id { + color: #999999; + display: inline-block; + padding-left: 10px; + } + } + &-time { + padding-right: 55px; } &-details { margin-top: 5px; - white-space: nowrap; + .flex-row(); + justify-content: space-between; } - &-id { + &-tag { + height: 36px; + margin-right: 16px; + padding: 0 12px; + border: 1px solid #6d3df5; + border-radius: 4px; font-size: 24px; line-height: 36px; - color: #999999; - padding-right: 22px; + color: #6d3df5; display: inline-block; } &-info { font-size: 28px; line-height: 40px; color: #333333; - margin-right: 16px; display: inline-block; + margin-right: 16px; &:last-child { margin-right: 0; } @@ -257,7 +274,7 @@ &__share-button { //flex: 2 2; - flex: 0 0 406px; + flex: 0 0 406px; width: 406px; .button(@height: 88px; @fontSize: 32px; @fontWeight: 500; @borderRadius: 44px;); //margin-left: 32px; diff --git a/src/components/partner-intro/index.tsx b/src/components/partner-intro/index.tsx index 96b270f..7aa4a55 100644 --- a/src/components/partner-intro/index.tsx +++ b/src/components/partner-intro/index.tsx @@ -4,28 +4,56 @@ import { Swiper } from '@taroify/core'; import { GoodJob } from '@taroify/icons'; import { useCallback, useEffect, useRef, useState } from 'react'; +import LoginDialog from '@/components/login-dialog'; import { PageUrl } from '@/constants/app'; +import useUserInfo from '@/hooks/use-user-info'; import { EarnType, UserProfitListItem } from '@/types/partner'; import { openCustomerServiceChat } from '@/utils/common'; -import { formatMoney, formatTimestamp, formatUserId, getLastProfitList } from '@/utils/partner'; +import { becomePartner, formatMoney, formatTimestamp, formatUserId, getLastProfitList } from '@/utils/partner'; import { navigateTo } from '@/utils/route'; +import { isNeedPhone, requestUserInfo } from '@/utils/user'; import './index.less'; const PREFIX = 'partner-intro'; export default function PartnerIntro() { - const handleConfirm = useCallback(() => { - navigateTo(PageUrl.GroupOwnerCertificate); - }, []); + const userInfo = useUserInfo(); + const needPhone = isNeedPhone(userInfo); + const [loginVisible, setLoginVisible] = useState(false); const handleOpenService = useCallback(() => { openCustomerServiceChat('https://work.weixin.qq.com/kfid/kfc4fcf6b109b3771d7'); }, []); - const handleJump = useCallback(() => { - navigateTo(PageUrl.PartnerShareVip); + const handleBindSuccess = useCallback(async () => { + await becomePartner(); + await requestUserInfo(); + setLoginVisible(false); }, []); + const handleBecomePartner = useCallback(() => { + if (needPhone) { + setLoginVisible(true); + return false; + } else { + handleBindSuccess(); + return true; + } + }, [handleBindSuccess, needPhone]); + + const handleConfirm = useCallback(() => { + if (!userInfo.isPartner && !handleBecomePartner()) { + return; + } + navigateTo(PageUrl.GroupOwnerCertificate); + }, [handleBecomePartner, userInfo.isPartner]); + + const handleJump = useCallback(() => { + if (!userInfo.isPartner && !handleBecomePartner()) { + return; + } + navigateTo(PageUrl.PartnerShareVip); + }, [handleBecomePartner, userInfo.isPartner]); const timerRef = useRef(null); const [bannerList, setBannerList] = useState([]); @@ -57,6 +85,19 @@ export default function PartnerIntro() { } }; }, [getBannerList]); + + const showedRef = useRef(false); + + useEffect(() => { + if (showedRef.current || !userInfo.userId) { + return; + } + showedRef.current = true; + if (!userInfo.isPartner) { + handleBecomePartner(); + } + }, [userInfo]); + return (
{bannerList.map((item, index) => ( -
{formatTimestamp(item.updatedAt)}
+
+
{formatTimestamp(item.updatedAt)}
+
+ 用户
{formatUserId(item.userId)}
+
+
-
{formatUserId(item.userId)}
-
- {[EarnType.CHAT_ACTIVITY_SHARE_L1, EarnType.CHAT_ACTIVITY_SHARE_L2].includes(item.earnType) - ? '主播被开聊' - : '会员支付'} -
+{formatMoney(item.amount, 1)}
+
+
分成收入
+
+ {[EarnType.CHAT_ACTIVITY_SHARE_L1, EarnType.CHAT_ACTIVITY_SHARE_L2].includes(item.earnType) + ? '主播被开聊' + : '会员支付'} +
+{formatMoney(item.amount)}
+
- 累计
{formatMoney(item.total, 1)}
+ 累计
{formatMoney(item.total)}
@@ -163,6 +211,10 @@ export default function PartnerIntro() { 赠送会员给好友
+ + {loginVisible && ( + setLoginVisible(false)} onSuccess={handleBindSuccess} needPhone={needPhone} /> + )}
); } diff --git a/src/constants/material.ts b/src/constants/material.ts index 7549d10..8940c84 100644 --- a/src/constants/material.ts +++ b/src/constants/material.ts @@ -3,6 +3,7 @@ export enum ProfileGroupType { Intention = 'intention', Experience = 'experience', Advantages = 'advantages', + Others = 'others', } export const ProfileTitleMap = { @@ -10,6 +11,7 @@ export const ProfileTitleMap = { [ProfileGroupType.Intention]: '求职意向', [ProfileGroupType.Experience]: '直播经验', [ProfileGroupType.Advantages]: '自身优势', + [ProfileGroupType.Others]: '身型、学历', }; export enum WorkedYears { @@ -19,6 +21,13 @@ export enum WorkedYears { MoreThreeYear = 3, } +export enum EducationType { + MiddleSchool = 1, + HighSchool = 2, + AssociateDegree = 3, + BachelorOrAbove = 4, +} + export enum GenderType { All = -1, MEN = 0, @@ -110,3 +119,15 @@ export const ANCHOR_READ_TITLE_MAP = { [AnchorReadType.Read]: '已读', [AnchorReadType.Unread]: '未读', }; +export const EDUCATION_TYPE_LABELS = { + [EducationType.MiddleSchool]: '初中', + [EducationType.HighSchool]: '职高/高中', + [EducationType.AssociateDegree]: '大专', + [EducationType.BachelorOrAbove]: '本科及以上', +}; +export const EDUCATION_TYPE_OPTIONS = [ + { label: EDUCATION_TYPE_LABELS[EducationType.MiddleSchool], value: EducationType.MiddleSchool }, + { label: EDUCATION_TYPE_LABELS[EducationType.HighSchool], value: EducationType.HighSchool }, + { label: EDUCATION_TYPE_LABELS[EducationType.AssociateDegree], value: EducationType.AssociateDegree }, + { label: EDUCATION_TYPE_LABELS[EducationType.BachelorOrAbove], value: EducationType.BachelorOrAbove }, +]; diff --git a/src/fragments/job/base/index.tsx b/src/fragments/job/base/index.tsx index 6b66e95..294c4fc 100644 --- a/src/fragments/job/base/index.tsx +++ b/src/fragments/job/base/index.tsx @@ -124,7 +124,6 @@ function JobFragment(props: IProps) { const handleSelectEmployType = useCallback( (value?: EmployType) => { - console.log('哈哈哈', value); setShowEmployTypeSelect(false); onClickEmployType(value!); }, diff --git a/src/fragments/profile/basic/index.tsx b/src/fragments/profile/basic/index.tsx index a1881dc..85f688c 100644 --- a/src/fragments/profile/basic/index.tsx +++ b/src/fragments/profile/basic/index.tsx @@ -23,9 +23,7 @@ function ProfileBasicFragment(props: IProps, ref) { const [name, setName] = useState(profile.name || ''); const [gender, setGender] = useState(profile.gender || GenderType.WOMEN); const [age, setAge] = useState(profile.age || ''); - const [height, setHeight] = useState(profile.height || ''); - const [weight, setWeight] = useState(profile.weight || ''); - const [shoeSize, setShoeSize] = useState(profile.shoeSize || ''); + const [workedSecCategoryStr, setWorkedSecCategoryStr] = useState(profile.workedSecCategoryStr || ''); const handleInputName = useCallback((e: BaseEventOrig) => { const value = e.detail.value || ''; @@ -40,41 +38,21 @@ function ProfileBasicFragment(props: IProps, ref) { setAge(string2Number(value)); }, []); - const handleInputHeight = useCallback((e: BaseEventOrig) => { - const value = e.detail.value || ''; - if (Number.isNaN(Number(value))) { - return; - } - setHeight(string2Number(value)); - }, []); - - const handleInputWeight = useCallback((e: BaseEventOrig) => { - const value = e.detail.value || ''; - if (Number.isNaN(Number(value))) { - return; - } - setWeight(string2Number(value)); - }, []); - - const handleInputShoeSize = useCallback((e: BaseEventOrig) => { - const value = e.detail.value || ''; - if (Number.isNaN(Number(value))) { - return; - } - setShoeSize(string2Number(value)); - }, []); - const handleGenderChange = useCallback((value: GenderType) => { log('handleGenderChange', value); setGender(value); }, []); + const handleInputWorkedSecCategoryStr = useCallback((e: BaseEventOrig) => { + const value = e.detail.value || ''; + setWorkedSecCategoryStr(value); + }, []); useImperativeHandle( ref, () => ({ - getData: () => ({ name, gender, age, height, weight, shoeSize }), + getData: () => ({ name, gender, age, workedSecCategoryStr }), }), - [name, gender, age, height, weight, shoeSize] + [name, gender, age, workedSecCategoryStr] ); return ( @@ -82,29 +60,17 @@ function ProfileBasicFragment(props: IProps, ref) { + + + - - - - - - - - - - - + + ); diff --git a/src/fragments/profile/experience/index.tsx b/src/fragments/profile/experience/index.tsx index 0c4dd7f..486f705 100644 --- a/src/fragments/profile/experience/index.tsx +++ b/src/fragments/profile/experience/index.tsx @@ -48,10 +48,9 @@ function ProfileExperienceFragment(props: IProps, ref) { const [workedYear, setWorkedYear] = useState(profile.workedYear); const [workedAccounts, setWorkedAccounts] = useState(profile.workedAccounts || ''); const [newAccountExperience, setNewAccountExperience] = useState(profile.newAccountExperience); - const [workedSecCategoryStr, setWorkedSecCategoryStr] = useState(profile.workedSecCategoryStr || ''); // const [style, setStyle] = useState(calcInitStyle(profile.style)); const [maxGmv, setMaxGmv] = useState(calcInitMaxGmv(profile?.maxGmv || 0)); - const [maxOnline, setMaxOnline] = useState(profile.maxOnline || ''); + // const [maxOnline, setMaxOnline] = useState(profile.maxOnline || ''); const handleSelectWorkYear = useCallback((newYear: WorkedYears) => { setWorkedYear(newYear); @@ -67,11 +66,6 @@ function ProfileExperienceFragment(props: IProps, ref) { setNewAccountExperience(value); }, []); - const handleInputWorkedSecCategoryStr = useCallback((e: BaseEventOrig) => { - const value = e.detail.value || ''; - setWorkedSecCategoryStr(value); - }, []); - // const handleStyleChange = useCallback((value: StyleType[]) => { // log('handleStyleChange', value); // setStyle(value); @@ -84,14 +78,14 @@ function ProfileExperienceFragment(props: IProps, ref) { } setMaxGmv(string2Number(value)); }, []); - - const handleInputMaxOnline = useCallback((e: BaseEventOrig) => { - const value = e.detail.value || ''; - if (Number.isNaN(Number(value))) { - return; - } - setMaxOnline(string2Number(value)); - }, []); + // + // const handleInputMaxOnline = useCallback((e: BaseEventOrig) => { + // const value = e.detail.value || ''; + // if (Number.isNaN(Number(value))) { + // return; + // } + // setMaxOnline(string2Number(value)); + // }, []); useImperativeHandle( ref, @@ -100,22 +94,21 @@ function ProfileExperienceFragment(props: IProps, ref) { workedYear, workedAccounts, newAccountExperience, - workedSecCategoryStr, // style: getStyleString(style.sort()), - maxOnline: maxOnline === '' ? undefined : maxOnline, + // maxOnline: maxOnline === '' ? undefined : maxOnline, maxGmv: maxGmv === '' ? undefined : getMaxGmv(Number(maxGmv)), }), }), - [workedYear, workedAccounts, newAccountExperience, workedSecCategoryStr, maxGmv, maxOnline] + [workedYear, workedAccounts, newAccountExperience, maxGmv] ); return (
- + - - + + - - - {/* @@ -140,9 +130,9 @@ function ProfileExperienceFragment(props: IProps, ref) { - - - + {/**/} + {/* */} + {/**/}
); } diff --git a/src/fragments/profile/intention/index.less b/src/fragments/profile/intention/index.less index 29d66ec..e987ae8 100644 --- a/src/fragments/profile/intention/index.less +++ b/src/fragments/profile/intention/index.less @@ -45,4 +45,8 @@ } } -} \ No newline at end of file + .transparent { + background: transparent; + padding: 0; + } +} diff --git a/src/fragments/profile/intention/index.tsx b/src/fragments/profile/intention/index.tsx index 0281b38..b12a9c4 100644 --- a/src/fragments/profile/intention/index.tsx +++ b/src/fragments/profile/intention/index.tsx @@ -3,12 +3,21 @@ import Taro from '@tarojs/taro'; import { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from 'react'; +import { BlCheckbox, BlCheckboxGroup } from '@/components/bl-checkbox'; import BlFormItem from '@/components/bl-form-item'; import { BlFormRadio, BlFormRadioGroup } from '@/components/bl-form-radio'; import BlFormSelect from '@/components/bl-form-select'; import { EventName, OpenSource, PageUrl } from '@/constants/app'; import { CITY_CODE_TO_NAME_MAP } from '@/constants/city'; -import { EmployType, EMPLOY_TYPE_TITLE_MAP, FULL_PRICE_OPTIONS, PART_PRICE_OPTIONS } from '@/constants/job'; +import { + EmployType, + EMPLOY_TYPE_TITLE_MAP, + FULL_PRICE_OPTIONS, + PART_PRICE_OPTIONS, + ALL_JOB_TYPES, + JobType, + JOB_TYPE_TITLE_MAP, +} from '@/constants/job'; import { SalaryRange } from '@/types/job'; import { MaterialProfile } from '@/types/material'; import { logWithPrefix } from '@/utils/common'; @@ -60,6 +69,12 @@ const getSalaryPrice = (fullSalary?: SalaryRange, partSalary?: SalaryRange) => { return price; }; +const getWorkedCategoryString = (workedCategory: JobType[]) => workedCategory.join(','); + +const getWorkedCategory = (workedCategory?: string): JobType[] => { + return workedCategory ? (workedCategory.split(',') as JobType[]).filter(v => ALL_JOB_TYPES.includes(v)) : []; +}; + function ProfileIntentionFragment(props: IProps, ref) { const { profile } = props; const [cityCodes, setCityCodes] = useState(calcInitCityCodes(profile.cityCodes || '')); @@ -67,6 +82,7 @@ function ProfileIntentionFragment(props: IProps, ref) { const [fullSalary, setFullSalary] = useState(calcSalarySelect(profile, true)); const [partSalary, setPartSalary] = useState(calcSalarySelect(profile, false)); const [acceptWorkForSit, setAcceptWorkForSit] = useState(profile.acceptWorkForSit); + const [workedCategory, setWorkedCategory] = useState(getWorkedCategory(profile.workedCategory)); const handleDeleteCity = useCallback( (deleteCode: string) => { @@ -85,7 +101,7 @@ function ProfileIntentionFragment(props: IProps, ref) { data => { log('handleSelectCity', data); realtimeLogger.info('handleSelectCity', data); - const { openSource, cityCode: code } = data; + const { cityCode: code } = data; // if (openSource !== OpenSource.AddIndentCity) { // return; // } @@ -118,6 +134,11 @@ function ProfileIntentionFragment(props: IProps, ref) { setAcceptWorkForSit(value); }, []); + const handleWorkedCategoryChange = useCallback((value: JobType[]) => { + log('handleWorkedCategoryChange', value); + setWorkedCategory(value); + }, []); + useEffect(() => { Taro.eventCenter.on(EventName.SELECT_CITY, handleSelectCity); return () => { @@ -132,10 +153,11 @@ function ProfileIntentionFragment(props: IProps, ref) { cityCodes: getCityCodeString(cityCodes), employType, acceptWorkForSit, + workedCategory: getWorkedCategoryString(workedCategory), ...getSalaryPrice(fullSalary, partSalary), }), }), - [cityCodes, employType, fullSalary, partSalary, acceptWorkForSit] + [cityCodes, employType, fullSalary, partSalary, acceptWorkForSit, workedCategory] ); return ( @@ -174,7 +196,7 @@ function ProfileIntentionFragment(props: IProps, ref) {
{isFullTimePriceRequired(employType) && ( - + )} {isPartTimePriceRequired(employType) && ( - + )} - + + + + {ALL_JOB_TYPES.filter(type => type !== JobType.All).map(type => { + return ; + })} + + ); } diff --git a/src/fragments/profile/others/index.less b/src/fragments/profile/others/index.less new file mode 100644 index 0000000..6260202 --- /dev/null +++ b/src/fragments/profile/others/index.less @@ -0,0 +1,15 @@ +@import '@/styles/common.less'; +@import '@/styles/variables.less'; + +.fragment-profile-others { + width: 100%; + + &__title { + font-weight: 400; + font-size: 32px; + line-height: 40px; + + + margin-bottom: 24px; + } +} diff --git a/src/fragments/profile/others/index.tsx b/src/fragments/profile/others/index.tsx new file mode 100644 index 0000000..be5b816 --- /dev/null +++ b/src/fragments/profile/others/index.tsx @@ -0,0 +1,94 @@ +import { BaseEventOrig, InputProps } from '@tarojs/components'; + +import { forwardRef, useCallback, useImperativeHandle, useState } from 'react'; + +import BlFormInput from '@/components/bl-form-input'; +import BlFormItem from '@/components/bl-form-item'; +import BlFormSelect from '@/components/bl-form-select'; +import { EDUCATION_TYPE_OPTIONS, EducationType } from '@/constants/material'; +import { MaterialProfile } from '@/types/material'; +import { logWithPrefix, string2Number } from '@/utils/common'; + +import './index.less'; + +interface IProps { + profile: Partial; +} + +const PREFIX = 'fragment-profile-others'; +const log = logWithPrefix(PREFIX); + +function ProfileOthersFragment(props: IProps, ref) { + const { profile } = props; + const [educationType, setEducationType] = useState(profile.educationType || ''); + const [height, setHeight] = useState(profile.height || ''); + const [weight, setWeight] = useState(profile.weight || ''); + const [shoeSize, setShoeSize] = useState(profile.shoeSize || ''); + + const handleInputHeight = useCallback((e: BaseEventOrig) => { + const value = e.detail.value || ''; + if (Number.isNaN(Number(value))) { + return; + } + setHeight(string2Number(value)); + }, []); + + const handleInputWeight = useCallback((e: BaseEventOrig) => { + const value = e.detail.value || ''; + if (Number.isNaN(Number(value))) { + return; + } + setWeight(string2Number(value)); + }, []); + + const handleInputShoeSize = useCallback((e: BaseEventOrig) => { + const value = e.detail.value || ''; + if (Number.isNaN(Number(value))) { + return; + } + setShoeSize(string2Number(value)); + }, []); + + const handleSelectEducationType = useCallback((type: EducationType) => { + setEducationType(type); + }, []); + + useImperativeHandle( + ref, + () => ({ + getData: () => ({ height, weight, shoeSize, educationType }), + }), + [height, weight, shoeSize, educationType] + ); + + return ( +
+
服饰等穿版品类必填,其他品类选填
+ + + + + + + + + + + + +
+ ); +} + +export default forwardRef(ProfileOthersFragment); diff --git a/src/fragments/profile/view/index.tsx b/src/fragments/profile/view/index.tsx index ff13fd0..088f33e 100644 --- a/src/fragments/profile/view/index.tsx +++ b/src/fragments/profile/view/index.tsx @@ -8,16 +8,22 @@ import DevDiv from '@/components/dev-div'; import SafeBottomPadding from '@/components/safe-bottom-padding'; import { OpenSource, PageUrl } from '@/constants/app'; import { CITY_CODE_TO_NAME_MAP } from '@/constants/city'; -import { FULL_PRICE_OPTIONS, PART_PRICE_OPTIONS } from '@/constants/job'; -import { ProfileGroupType, ProfileTitleMap, WORK_YEAR_OPTIONS } from '@/constants/material'; +import { FULL_PRICE_OPTIONS, JOB_TYPE_TITLE_MAP, JobType, PART_PRICE_OPTIONS } from '@/constants/job'; +import { + EDUCATION_TYPE_LABELS, + GenderType, + ProfileGroupType, + ProfileTitleMap, + WORK_YEAR_OPTIONS, +} from '@/constants/material'; import { MaterialProfile } from '@/types/material'; -import { logWithPrefix, isDesktop } from '@/utils/common'; -import { getBasicInfo, sortVideos } from '@/utils/material'; +import { isDesktop, logWithPrefix } from '@/utils/common'; +import { sortVideos } from '@/utils/material'; import { navigateTo } from '@/utils/route'; import './index.less'; -import onChangeEventDetail = SwiperProps.onChangeEventDetail; import { JoinGroupHint } from '@/components/join-group-hint'; +import onChangeEventDetail = SwiperProps.onChangeEventDetail; interface IProps { editable: boolean; @@ -30,7 +36,7 @@ const log = logWithPrefix(PREFIX); const DEFAULT_TEXT = '未填写'; const getIndentCity = (codeString: string = '') => { - const codes = (codeString||'').split('、'); + const codes = (codeString || '').split('、'); const cityNames: string[] = []; codes.forEach(code => { const cityName = CITY_CODE_TO_NAME_MAP.get(code); @@ -63,7 +69,14 @@ const getWorkYear = (year: number) => { const y = Math.min(year, 3); return WORK_YEAR_OPTIONS.find(option => option.value === y)?.label || `${y}年`; }; - +const getWorkedCategory = (workedCategory?: string): string => { + return workedCategory + ? (workedCategory.split(',') as JobType[]) + .map(v => (v !== JobType.All ? JOB_TYPE_TITLE_MAP[v] : null)) + .filter(Boolean) + .join('、') + : ''; +}; const getDataGroup = (profile: MaterialProfile | null) => { if (!profile) { return []; @@ -77,6 +90,7 @@ const getDataGroup = (profile: MaterialProfile | null) => { { title: '兼职薪资', value: getIndentPrice(profile.partyTimeMinPrice, profile.partyTimeMaxPrice, false) || '' }, { title: '意向城市', value: getIndentCity(profile.cityCodes) || DEFAULT_TEXT }, { title: '是否接受坐班', value: profile.acceptWorkForSit ? '是' : '否' }, + { title: '意向品类', value: getWorkedCategory(profile.workedCategory) || DEFAULT_TEXT, fullLine: true }, ], }, { @@ -86,9 +100,18 @@ const getDataGroup = (profile: MaterialProfile | null) => { { title: '直播年限', value: getWorkYear(profile.workedYear) || DEFAULT_TEXT }, { title: '直播过的账号', value: profile.workedAccounts || DEFAULT_TEXT }, { title: '自然流起号经验', value: Boolean(profile.newAccountExperience) ? '有' : '无' }, - { title: '直播过的品类', value: profile.workedSecCategoryStr || DEFAULT_TEXT }, + // { title: '直播过的品类', value: profile.workedSecCategoryStr || DEFAULT_TEXT }, { title: '最高GMV', value: profile.maxGmv ? `${profile.maxGmv / 10000}万` : DEFAULT_TEXT }, - { title: '最高在线人数', value: profile.maxOnline || DEFAULT_TEXT }, + ], + }, + { + title: ProfileTitleMap[ProfileGroupType.Others], + type: ProfileGroupType.Others, + items: [ + { title: '身高', value: profile.height ? `${profile.height}cm` : DEFAULT_TEXT }, + { title: '体重', value: profile.weight ? `${profile.weight}kg` : DEFAULT_TEXT }, + { title: '鞋码', value: profile.shoeSize ? `${profile.shoeSize}码` : DEFAULT_TEXT }, + { title: '学历', value: EDUCATION_TYPE_LABELS[profile.educationType] || DEFAULT_TEXT }, ], }, { @@ -99,6 +122,16 @@ const getDataGroup = (profile: MaterialProfile | null) => { ]; }; +export const getBasicInfo = (profile: Pick) => { + const result: string[] = []; + if (typeof profile.age !== 'undefined' && profile.age !== null) { + result.push(`${profile.age}岁`); + } + result.push(profile.gender === GenderType.MEN ? '男' : '女'); + + return result.join('·'); +}; + export default function ProfileViewFragment(props: IProps) { const { profile, editable, onDev } = props; const [coverIndex, setCoverIndex] = useState(0); @@ -221,7 +254,9 @@ export default function ProfileViewFragment(props: IProps) { )} -
{getBasicInfo(profile)}
+
+
{getBasicInfo(profile)}
+
{dataGroup.map((data, index: number) => ( diff --git a/src/hooks/use-city-operators.tsx b/src/hooks/use-city-operators.tsx index a3756d4..ccb087c 100644 --- a/src/hooks/use-city-operators.tsx +++ b/src/hooks/use-city-operators.tsx @@ -1,9 +1,9 @@ import { useSelector } from 'react-redux'; -import { selectCityOperators } from '@/store/selector'; +import { selectCityConfigs } from '@/store/selector'; function useCityOperators() { - const data = useSelector(selectCityOperators); + const data = useSelector(selectCityConfigs); return data || []; } diff --git a/src/hooks/use-user-info.tsx b/src/hooks/use-user-info.tsx index d899414..e3f3d7d 100644 --- a/src/hooks/use-user-info.tsx +++ b/src/hooks/use-user-info.tsx @@ -3,8 +3,8 @@ import { useSelector } from 'react-redux'; import { selectUserInfo } from '@/store/selector/user'; function useUserInfo() { - const useInfo = useSelector(selectUserInfo); - return useInfo; + const userInfo = useSelector(selectUserInfo); + return userInfo; } export default useUserInfo; diff --git a/src/http/api.ts b/src/http/api.ts index 30e7e1c..d733e38 100644 --- a/src/http/api.ts +++ b/src/http/api.ts @@ -95,5 +95,5 @@ export enum API { GET_AUTHED_GROUP_LIST = '/partner/getAuthedGroupList', GET_STAFF_CODE = '/partner/staff/{cityCode}', // 所有城市运营 - GET_ALL_CITY_OPERATOR = '/group/getAllGroup', + GET_ALL_CITY_CONFIGS = '/group/getAllGroup', } diff --git a/src/pages/anchor/index.tsx b/src/pages/anchor/index.tsx index 18cff20..3c8b611 100644 --- a/src/pages/anchor/index.tsx +++ b/src/pages/anchor/index.tsx @@ -115,7 +115,6 @@ export default function AnchorPage() { const handleChangeSelectJob = useCallback((select?: JobManageInfo) => { log('select job change', select); setSelectJob(select); - console.log('哈哈哈', !select); setOpenPopup(!select); setLastSelectMyJobId(select?.id || ''); }, []); diff --git a/src/pages/material-create-profile/index.less b/src/pages/material-create-profile/index.less index f555b7d..41538ce 100644 --- a/src/pages/material-create-profile/index.less +++ b/src/pages/material-create-profile/index.less @@ -10,11 +10,27 @@ left: 24px; right: 24px; bottom: 0; - background: #F5F6FA; + background: #f5f6fa; } &__submit-btn { .button(@width: 100%, @height: 80px, @fontSize: 32px, @fontWeight: 400, @borderRadius: 48px); bottom: 40px; } -} \ No newline at end of file + + &__skip-btn-wrapper { + text-align: center; + bottom: 60px; + } + + &__skip-btn { + color: @blHighlightColor; + width: 161px; + height: 40px; + font-weight: 400; + font-size: 32px; + line-height: 40px; + text-align: center; + display: inline-block; + } +} diff --git a/src/pages/material-create-profile/index.tsx b/src/pages/material-create-profile/index.tsx index 57bbce3..06f91f2 100644 --- a/src/pages/material-create-profile/index.tsx +++ b/src/pages/material-create-profile/index.tsx @@ -21,25 +21,28 @@ import { navigateBack } from '@/utils/route'; import Toast from '@/utils/toast'; import './index.less'; +import ProfileOthersFragment from '@/fragments/profile/others'; const PREFIX = 'page-material-create-profile'; const log = logWithPrefix(PREFIX); const REQUIRE_KEYS = { - [ProfileGroupType.Basic]: ['name', 'gender', 'age', 'height', 'weight'], + [ProfileGroupType.Basic]: ['name', 'gender', 'age'], [ProfileGroupType.Intention]: [ 'cityCodes', 'employType', - 'acceptWorkForSit', 'fullTimeMinPrice', 'fullTimeMaxPrice', 'partyTimeMinPrice', 'partyTimeMaxPrice', ], - [ProfileGroupType.Experience]: ['workedYear'], + [ProfileGroupType.Experience]: [], [ProfileGroupType.Advantages]: [], + [ProfileGroupType.Others]: [], }; +const COULD_SKIP = [ProfileGroupType.Experience, ProfileGroupType.Others]; + const CONDITIONAL_REQUIRED_KEYS = { [ProfileGroupType.Intention]: [ ['fullTimeMinPrice', data => isFullTimePriceRequired(data.employType)], @@ -52,11 +55,13 @@ const CONDITIONAL_REQUIRED_KEYS = { const getNextStepGroupType = (curType: ProfileGroupType) => { switch (curType) { case ProfileGroupType.Basic: - return ProfileGroupType.Advantages; - case ProfileGroupType.Intention: return ProfileGroupType.Experience; - case ProfileGroupType.Experience: + case ProfileGroupType.Intention: return ProfileGroupType.Basic; + case ProfileGroupType.Experience: + return ProfileGroupType.Others; + case ProfileGroupType.Others: + return ProfileGroupType.Advantages; default: return null; } @@ -88,7 +93,16 @@ export default function MaterialCreateProfile() { ? ProfileExperienceFragment : groupType === ProfileGroupType.Advantages ? ProfileAdvantagesFragment - : Fragment; + : groupType === ProfileGroupType.Others + ? ProfileOthersFragment + : Fragment; + + const handleSkip = useCallback(() => { + const nextType = getNextStepGroupType(groupType); + if (nextType) { + setGroupType(nextType); + } + }, [groupType]); const handleSubmit = useCallback(async () => { try { @@ -123,14 +137,23 @@ export default function MaterialCreateProfile() { Taro.setNavigationBarTitle({ title }); }, [groupType]); + const couldSkip = COULD_SKIP.includes(groupType); + return (
- + {couldSkip && ( +
+
+ 跳过 +
+
+ )}
diff --git a/src/pages/material-edit-profile/index.tsx b/src/pages/material-edit-profile/index.tsx index 039b740..ef07e6c 100644 --- a/src/pages/material-edit-profile/index.tsx +++ b/src/pages/material-edit-profile/index.tsx @@ -12,6 +12,7 @@ import ProfileAdvantagesFragment from '@/fragments/profile/advantages'; import ProfileBasicFragment from '@/fragments/profile/basic'; import ProfileExperienceFragment from '@/fragments/profile/experience'; import ProfileIntentionFragment from '@/fragments/profile/intention'; +import ProfileOthersFragment from '@/fragments/profile/others'; import { MaterialProfile } from '@/types/material'; import { logWithPrefix } from '@/utils/common'; import { collectEvent } from '@/utils/event'; @@ -37,7 +38,9 @@ export default function MaterialEdit() { ? ProfileExperienceFragment : groupType === ProfileGroupType.Advantages ? ProfileAdvantagesFragment - : Fragment; + : groupType === ProfileGroupType.Others + ? ProfileOthersFragment + : Fragment; log('MaterialEdit', groupType, ref); const handleSubmit = useCallback(async () => { diff --git a/src/store/actions/app.ts b/src/store/actions/app.ts index 6ff9be5..bac83fc 100644 --- a/src/store/actions/app.ts +++ b/src/store/actions/app.ts @@ -2,7 +2,7 @@ import { RoleType, PageType } from '@/constants/app'; import { LocationInfo } from '@/types/location'; import { AppState } from '@/types/store'; -import { CHANGE_ROLE_TYPE, CHANGE_HOME_PAGE, SET_LOCATION_INFO, SET_SERVICE_URLS } from '../constants'; +import { CHANGE_ROLE_TYPE, CHANGE_HOME_PAGE, SET_LOCATION_INFO, SET_CITY_CONFIGS } from '../constants'; export const changeRoleType = (value: RoleType) => ({ type: CHANGE_ROLE_TYPE, value }); @@ -10,4 +10,4 @@ export const changeHomePage = (value: PageType) => ({ type: CHANGE_HOME_PAGE, va export const setLocationInfo = (value: LocationInfo) => ({ type: SET_LOCATION_INFO, value }); -export const setCityOperators = (value: AppState['cityOperators']) => ({ type: SET_SERVICE_URLS, value }); +export const setCityConfigs = (value: AppState['cityConfigs']) => ({ type: SET_CITY_CONFIGS, value }); diff --git a/src/store/constants.ts b/src/store/constants.ts index 953d96f..5251658 100644 --- a/src/store/constants.ts +++ b/src/store/constants.ts @@ -6,4 +6,4 @@ export const SET_BIND_PHONE = 'SET_BIND_PHONE'; export const SET_USER_MESSAGE = 'SET_USER_MESSAGE'; export const SET_INVITE_CODE = 'SET_INVITE_CODE'; export const SET_JOB_ID = 'SET_JOB_ID'; -export const SET_SERVICE_URLS = 'SET_SERVICE_URLS'; +export const SET_CITY_CONFIGS = 'SET_CITY_CONFIGS'; diff --git a/src/store/reducers/app.ts b/src/store/reducers/app.ts index 74dc809..8941029 100644 --- a/src/store/reducers/app.ts +++ b/src/store/reducers/app.ts @@ -7,7 +7,7 @@ import { CacheKey } from '@/constants/cache-key'; import { LocationInfo } from '@/types/location'; import { AppState } from '@/types/store'; -import { CHANGE_ROLE_TYPE, CHANGE_HOME_PAGE, SET_LOCATION_INFO, SET_SERVICE_URLS } from '../constants'; +import { CHANGE_ROLE_TYPE, CHANGE_HOME_PAGE, SET_LOCATION_INFO, SET_CITY_CONFIGS } from '../constants'; const DEFAULT_LOCATION: LocationInfo = { provinceCode: '440000', @@ -23,7 +23,7 @@ const INIT_STATE: AppState = { roleType: defaultAppMode, homePageType: defaultAppMode === RoleType.Company ? PageType.Anchor : PageType.JOB, location: Taro.getStorageSync(CacheKey.CACHE_LOCATION_INFO) || DEFAULT_LOCATION, - cityOperators: [], + cityConfigs: [], }; const appState = (state: AppState = INIT_STATE, action: Action): AppState => { @@ -34,8 +34,8 @@ const appState = (state: AppState = INIT_STATE, action: Action): AppState => { return { ...state, roleType: value }; case CHANGE_HOME_PAGE: return { ...state, homePageType: value }; - case SET_SERVICE_URLS: - return { ...state, cityOperators: value }; + case SET_CITY_CONFIGS: + return { ...state, cityConfigs: value }; case SET_LOCATION_INFO: Taro.setStorageSync(CacheKey.CACHE_LOCATION_INFO, value); return { ...state, location: value }; diff --git a/src/store/selector/app.ts b/src/store/selector/app.ts index 84186cc..b15c0aa 100644 --- a/src/store/selector/app.ts +++ b/src/store/selector/app.ts @@ -6,4 +6,4 @@ export const selectHomePageType = (state: IState) => state.appState.homePageType export const selectLocation = (state: IState) => state.appState.location; -export const selectCityOperators = (state: IState) => state.appState.cityOperators || {}; +export const selectCityConfigs = (state: IState) => state.appState.cityConfigs || []; diff --git a/src/types/location.ts b/src/types/location.ts index 3827722..390f90a 100644 --- a/src/types/location.ts +++ b/src/types/location.ts @@ -21,7 +21,7 @@ export interface GetCityCodeRequest { longitude: number; // 经度,范围为-180~180,负数表示西经 } -export interface CityOperatorListItem { +export interface CityConfigListItem { id: number; staffId: number; staffName: string; @@ -30,4 +30,6 @@ export interface CityOperatorListItem { groupLink: string; created: string; updated: string; + price: number | null; + sendCount: number | null; } diff --git a/src/types/material.ts b/src/types/material.ts index c23fd9e..90019c6 100644 --- a/src/types/material.ts +++ b/src/types/material.ts @@ -1,5 +1,12 @@ import { EmployType } from '@/constants/job'; -import { AnchorReadType, AnchorSortType, GenderType, ProfileCreateSource, WorkedYears } from '@/constants/material'; +import { + AnchorReadType, + AnchorSortType, + EducationType, + GenderType, + ProfileCreateSource, + WorkedYears, +} from '@/constants/material'; import { IPaginationRequest, IPaginationResponse } from '@/types/common'; export interface MaterialVideoInfo { @@ -51,6 +58,7 @@ export interface MaterialProfile { filledItems: number; // 已填资料项数 created: number; // 时间戳 updated: number; // 时间戳 + educationType: EducationType; } export interface AnchorInfo { diff --git a/src/types/store.ts b/src/types/store.ts index 37c2c38..0e8cc53 100644 --- a/src/types/store.ts +++ b/src/types/store.ts @@ -2,7 +2,7 @@ import { RoleType, PageType } from '@/constants/app'; import { UserMessage } from '@/types/message'; import { PartnerInfo } from '@/types/partner'; -import { LocationInfo } from './location'; +import { CityConfigListItem, LocationInfo } from './location'; import { UserInfo } from './user'; export interface IState { @@ -17,8 +17,5 @@ export interface AppState { roleType: RoleType; homePageType: PageType; location: LocationInfo; - cityOperators: Array<{ - cityCode: string; - groupLink: string; - }>; + cityConfigs: CityConfigListItem[]; } diff --git a/src/utils/location.ts b/src/utils/location.ts index cfb49bb..b71a5a3 100644 --- a/src/utils/location.ts +++ b/src/utils/location.ts @@ -6,9 +6,9 @@ import { CITY_CODE_TO_NAME_MAP, COUNTY_CODE_TO_NAME_MAP, PROVINCE_CODE_TO_NAME_M import http from '@/http'; import { API } from '@/http/api'; import store from '@/store'; -import { setLocationInfo, setCityOperators } from '@/store/actions'; +import { setLocationInfo, setCityConfigs } from '@/store/actions'; import { selectLocation } from '@/store/selector'; -import { CityOperatorListItem, GetCityCodeRequest, LocationInfo } from '@/types/location'; +import { CityConfigListItem, GetCityCodeRequest, LocationInfo } from '@/types/location'; import { authorize, getWxSetting } from './wx'; @@ -135,14 +135,7 @@ export async function requestLocation(force: boolean = false) { return location; } -export async function requestCityOperators() { - const list = await http.get(API.GET_ALL_CITY_OPERATOR); - store.dispatch( - setCityOperators( - (list || []).map(it => ({ - cityCode: it.cityCode, - groupLink: it.groupLink, - })) - ) - ); +export async function requestCityConfigs() { + const list = await http.get(API.GET_ALL_CITY_CONFIGS); + store.dispatch(setCityConfigs(list)); } diff --git a/src/utils/material.ts b/src/utils/material.ts index 140225a..9870e0c 100644 --- a/src/utils/material.ts +++ b/src/utils/material.ts @@ -2,7 +2,7 @@ import Taro from '@tarojs/taro'; import { PageUrl } from '@/constants/app'; import { CollectEventName } from '@/constants/event'; -import { GenderType, MaterialViewSource } from '@/constants/material'; +import { EDUCATION_TYPE_LABELS, GenderType, MaterialViewSource } from '@/constants/material'; import { MessageSubscribeIds } from '@/constants/subscribe'; import http from '@/http'; import { API } from '@/http/api'; @@ -44,7 +44,9 @@ const updateUserIfNeed = async () => { await requestUserInfo(); }; -export const getBasicInfo = (profile: Pick) => { +export const getBasicInfo = ( + profile: Pick +) => { const result: string[] = []; if (typeof profile.age !== 'undefined' && profile.age !== null) { result.push(`${profile.age}岁`); @@ -59,6 +61,9 @@ export const getBasicInfo = (profile: Pick getUserInfo().userId; export const isValidUserInfo = (info: UserInfo) => !!info.userId; export const isNeedLogin = (info: UserInfo) => !info.isBindPhone; -// export const isNeedLogin = (info: UserInfo) => !info.isBindPhone || info.userId === '218396277145075712'; +// export const isNeedLogin = (info: UserInfo) => !info.isBindPhone || info.userId === '171633767918600192'; export const isNeedPhone = (info: UserInfo) => isNeedLogin(info) || !info.phone;