diff --git a/src/components/search-city/index.less b/src/components/search-city/index.less new file mode 100644 index 0000000..537c4bb --- /dev/null +++ b/src/components/search-city/index.less @@ -0,0 +1,123 @@ +@import '@/styles/variables.less'; + +.search-city { + background: #FFF; + + &__position-title { + font-size: 24px; + color: @blColorG1; + padding: 0 24px; + margin-top: 18px; + } + + &__position-city { + font-size: 30px; + font-weight: bold; + color: @blColor; + padding: 0 24px; + margin-top: 18px; + } + + &__hot-city-title { + height: 48px; + font-size: 24px; + line-height: 48px; + padding: 0 24px; + color: #999; + background: #f2f5f7; + margin-top: 18px; + } + + &__hot-city-container { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-content: space-between; + width: 630px; + padding: 12px 90px 26px 30px; + background: #FFFFFF; + } + + &__hot-city-item { + width: 140px; + height: 58px; + font-size: 28px; + line-height: 58px; + text-align: center; + border-radius: 58px; + border: 2px solid @blColorG1; + margin-top: 18px; + } + + &__indexes-list { + width: 100%; + /* 兼容 iOS < 11.2 */ + padding-bottom: constant(safe-area-inset-bottom); + /* 兼容 iOS >= 11.2 */ + padding-bottom: env(safe-area-inset-bottom); + } + + &__indexes-fragment {} + + &__indexes-anchor { + height: 48px; + font-size: 24px; + line-height: 48px; + padding: 0 24px; + color: @blColorG1; + background: #f2f5f7; + } + + &__indexes-cell { + position: relative; + font-size: 28px; + padding: 30px 24px; + color: @blColor; + + &::after { + content: ''; + position: absolute; + border-bottom: 1rpx solid #eaeef1; + transform: scaleY(0.5); + bottom: 0; + right: 0; + left: 24px; + } + } + + &__indexes-bar { + width: 44rpx; + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-start; + position: fixed; + right: 10px; + } + + &__indexes-bar-item { + font-size: 22px; + color: @blColor; + white-space: nowrap; + display: flex; + align-items: center; + justify-content: center; + } + + &__indexes-index-alert { + position: absolute; + z-index: 20; + width: 160px; + height: 160px; + left: 50%; + top: 50%; + margin-left: -80px; + margin-top: -80px; + border-radius: 80px; + text-align: center; + line-height: 160px; + font-size: 70px; + color: #FFFFFF; + background-color: rgba(0, 0, 0, 0.5); + } +} \ No newline at end of file diff --git a/src/components/search-city/index.tsx b/src/components/search-city/index.tsx new file mode 100644 index 0000000..727ba00 --- /dev/null +++ b/src/components/search-city/index.tsx @@ -0,0 +1,225 @@ +import { BaseEventOrig, InputProps, ScrollView } from '@tarojs/components'; +import Taro from '@tarojs/taro'; + +import { Search } from '@taroify/core'; +import { useCallback, useEffect, useState } from 'react'; + +import { CITY_CODE_TO_NAME_MAP, CITY_INDEXES_LIST, GROUP_CITY_INDEXES_LIST } from '@/constants/city'; +import { logWithPrefix } from '@/utils/common'; + +import './index.less'; + +interface Item { + cityCode: number | string; + cityName: string; + keyword: string; +} + +const PREFIX = 'search-city'; +const HOT_CITY = [ + { cityCode: 110100, cityName: '北京' }, + { cityCode: 310100, cityName: '上海' }, + { cityCode: 440100, cityName: '广州' }, + { cityCode: 440300, cityName: '深圳' }, + { cityCode: 330100, cityName: '杭州' }, + { cityCode: 430100, cityName: '长沙' }, + { cityCode: 420100, cityName: '武汉' }, + { cityCode: 350200, cityName: '厦门' }, + { cityCode: 610100, cityName: '西安' }, + { cityCode: 410100, cityName: '郑州' }, + { cityCode: 510100, cityName: '成都' }, + { cityCode: 340100, cityName: '合肥' }, +]; + +const OFFSET_INDEX_SIZE = 2; +const log = logWithPrefix(PREFIX); +const realtimeLogger = Taro.getRealtimeLogManager(); +realtimeLogger.tag(PREFIX); +const useHeight = () => { + const [winHeight, setWinHeight] = useState(0); + const [indexItemHeight, setIndexItemHeight] = useState(0); + + useEffect(() => { + const windowInfo = Taro.getWindowInfo(); + const windowHeight = windowInfo.windowHeight; + setWinHeight(windowHeight); + // 上下预留两个选项高度的空白 + setIndexItemHeight(Math.floor(windowHeight / (26 + OFFSET_INDEX_SIZE * 2))); + }, []); + + return [winHeight, indexItemHeight]; +}; +export interface SearchCityProps { + onSelectCity: (cityCode: string) => void; + currentCity?: string; + forGroup?: boolean; + offset?: number; +} + +export default function SearchCity({ onSelectCity, currentCity = '', forGroup = false, offset = 0 }: SearchCityProps) { + const [winHeight, indexItemHeight] = useHeight(); + const [touchAnchor, setTouchAnchor] = useState(); + const [touchMoving, setTouchMoving] = useState(false); + const [searchResult, setSearchResult] = useState([]); + const showSearchList = searchResult.length > 0; + const CITY_LIST = forGroup ? GROUP_CITY_INDEXES_LIST : CITY_INDEXES_LIST; + + const handleSearchChange = useCallback((event: BaseEventOrig) => { + const value = event.detail.value; + log('handleSearchChange', value); + if (!value) { + setSearchResult([]); + return; + } + const result: Item[] = []; + CITY_LIST.forEach(obj => { + obj.data.forEach(city => { + if (city.keyword.includes(value.toLocaleUpperCase())) { + result.push({ ...city }); + } + }); + }); + setSearchResult(result); + }, []); + + const handleSelectCity = useCallback( + (e: React.MouseEvent) => { + const cityCode = e.currentTarget.dataset.code; + onSelectCity(String(cityCode)); + }, + [onSelectCity] + ); + + const handleTouchStart = useCallback( + (e: React.TouchEvent) => { + const pageY = e.touches[0].pageY; + const index = Math.floor(pageY / indexItemHeight) - OFFSET_INDEX_SIZE; + if (index < 0 || index >= CITY_LIST.length) { + return; + } + const item = CITY_LIST[index]; + if (item) { + setTouchMoving(true); + setTouchAnchor(item.letter); + } + }, + [indexItemHeight] + ); + + const handleTouchMove = useCallback( + (e: React.TouchEvent) => { + const pageY = e.touches[0].pageY; + const index = Math.floor(pageY / indexItemHeight) - OFFSET_INDEX_SIZE; + if (index < 0 || index >= CITY_LIST.length) { + return; + } + const item = CITY_LIST[index]; + item && setTouchAnchor(item.letter); + }, + [indexItemHeight] + ); + + const handleTouchEnd = useCallback((e: React.TouchEvent) => { + e.stopPropagation(); + setTouchMoving(false); + log('touch end'); + }, []); + + const handleClickAnchor = useCallback((anchor: string) => { + setTouchAnchor(anchor); + log('click anchor', anchor); + }, []); + + return ( +
+ + + {showSearchList && ( +
+ {searchResult.map(city => ( +
+ {city.cityName} +
+ ))} +
+ )} + {!showSearchList && ( +
+
当前城市
+
{CITY_CODE_TO_NAME_MAP.get(currentCity)}
+
热门城市
+
+ {HOT_CITY.map(city => ( +
+ {city.cityName} +
+ ))} +
+
+ {CITY_LIST.map(item => { + return ( +
+
+ {item.letter} +
+ {item.data.map(city => ( +
+ {city.cityName} +
+ ))} +
+ ); + })} +
+
+ )} +
+
+ {!showSearchList && ( +
+ {CITY_LIST.map(item => { + return ( +
handleClickAnchor(item.letter)} + > + {item.letter} +
+ ); + })} +
+ )} + {touchAnchor && touchMoving &&
{touchAnchor}
} +
+
+ ); +} diff --git a/src/components/user-batch-publish/index.less b/src/components/user-batch-publish/index.less index e42bfeb..f43a4df 100644 --- a/src/components/user-batch-publish/index.less +++ b/src/components/user-batch-publish/index.less @@ -3,7 +3,6 @@ .user-batch-publish { padding: 16px 24px; - padding-bottom: 200px; &__header-image { width: 100%; diff --git a/src/constants/city.ts b/src/constants/city.ts index edbf6d6..77ac332 100644 --- a/src/constants/city.ts +++ b/src/constants/city.ts @@ -5859,3 +5859,151 @@ export const CITY_INDEXES_LIST = [ ], }, ]; + +export const GROUP_CITY_INDEXES_LIST = [ + { + letter: 'C', + data: [ + { + cityCode: '500100', + cityName: '重庆', + keyword: 'CHONGQING重庆', + }, + { + cityCode: '510100', + cityName: '成都', + keyword: 'CHENGDOU成都', + }, + ], + }, + { + letter: 'D', + data: [ + { + cityCode: '441900', + cityName: '东莞', + keyword: 'DONGGUAN东莞', + }, + ], + }, + { + letter: 'F', + data: [ + { + cityCode: '440600', + cityName: '佛山', + keyword: 'FUSHAN佛山', + }, + { + cityCode: '350100', + cityName: '福州', + keyword: 'FUZHOU福州', + }, + ], + }, + { + letter: 'G', + data: [ + { + cityCode: '440100', + cityName: '广州', + keyword: 'GUANGZHOU广州', + }, + ], + }, + { + letter: 'H', + data: [ + { + cityCode: '340100', + cityName: '合肥', + keyword: 'HEFEI合肥', + }, + ], + }, + { + letter: 'N', + data: [ + { + cityCode: '320100', + cityName: '南京', + keyword: 'NANJING南京', + }, + ], + }, + { + letter: 'Q', + data: [ + { + cityCode: '370200', + cityName: '青岛', + keyword: 'QINGDAO青岛', + }, + ], + }, + { + letter: 'S', + data: [ + { + cityCode: '310100', + cityName: '上海', + keyword: 'SHANGHAI上海', + }, + { + cityCode: '440300', + cityName: '深圳', + keyword: 'SHENZHEN深圳', + }, + { + cityCode: '320500', + cityName: '苏州', + keyword: 'SUZHOU苏州', + }, + { + cityCode: '330300', + cityName: '温州', + keyword: 'WENZHOU温州', + }, + ], + }, + { + letter: 'T', + data: [ + { + cityCode: '120100', + cityName: '天津', + keyword: 'TIANJIN天津', + }, + ], + }, + { + letter: 'W', + data: [ + { + cityCode: '420100', + cityName: '武汉', + keyword: 'WUHAN武汉', + }, + ], + }, + { + letter: 'X', + data: [ + { + cityCode: '610100', + cityName: '西安', + keyword: 'XIAN西安', + }, + ], + }, + { + letter: 'Z', + data: [ + { + cityCode: '410100', + cityName: '郑州', + keyword: 'ZHENGZHOU郑州', + }, + ], + }, +]; diff --git a/src/constants/group.ts b/src/constants/group.ts index 571d352..5d649bd 100644 --- a/src/constants/group.ts +++ b/src/constants/group.ts @@ -33,28 +33,28 @@ export const GROUP_STATUS_OPTIONS = [ ]; export const GROUPS: GroupItem[] = [ - { title: '【杭州】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfc223f495e159af95e' }, - { title: '【广州】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfcb4b88b8abb7a7c8b' }, - { title: '【深圳】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfcfe70d8736e14bb64' }, - { title: '【北京】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfcb119c94575e91262' }, - { title: '【上海】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfc4189e68429cf07f8' }, - { title: '【郑州】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfcd1c53b7bf8ecdb97' }, - { title: '【长沙】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfc76be8f2b3f8aa437' }, - { title: '【成都】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfcf75cefbdc62946fa' }, - { title: '【重庆】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfcd7008f747d545f83' }, - { title: '【武汉】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfc047c94f8c709b395' }, - { title: '【厦门】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfc2007a895cb48464b' }, - { title: '【西安】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfc34768971b7354220' }, - { title: '【合肥】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfc41c9785cc2035277' }, - { title: '【南京】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfcc6dc8d0a9692b70e' }, - { title: '【青岛】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfce8d7a68190f6a1d2' }, - { title: '【佛山】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfcfac1132df386fac8' }, - { title: '【东莞】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfcb2b0e39026f7dddc' }, - { title: '【苏州】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfc4642f90a6e3528ff' }, - { title: '【福州】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfc126483dedadde82b' }, - { title: '【泉州】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfc4c8c42b1a9337aaf' }, - { title: '【温州】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfcb0ea5f197a18b335' }, - { title: '【天津】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfcda46c23dade6f6a3' }, - { title: '【昆明】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfcf2aebcbf3d46d9cd' }, - { title: '【全国】', serviceUrl: 'https://work.weixin.qq.com/kfid/kfcc60ac7b6420787a8' }, + { title: '【杭州】', cityCode: 330100, serviceUrl: 'https://work.weixin.qq.com/kfid/kfc223f495e159af95e' }, + { title: '【广州】', cityCode: 440100, serviceUrl: 'https://work.weixin.qq.com/kfid/kfcb4b88b8abb7a7c8b' }, + { title: '【深圳】', cityCode: 440300, serviceUrl: 'https://work.weixin.qq.com/kfid/kfcfe70d8736e14bb64' }, + { title: '【北京】', cityCode: 110100, serviceUrl: 'https://work.weixin.qq.com/kfid/kfcb119c94575e91262' }, + { title: '【上海】', cityCode: 310100, serviceUrl: 'https://work.weixin.qq.com/kfid/kfc4189e68429cf07f8' }, + { title: '【郑州】', cityCode: 410100, serviceUrl: 'https://work.weixin.qq.com/kfid/kfcd1c53b7bf8ecdb97' }, + { title: '【长沙】', cityCode: 430100, serviceUrl: 'https://work.weixin.qq.com/kfid/kfc76be8f2b3f8aa437' }, + { title: '【成都】', cityCode: 510100, serviceUrl: 'https://work.weixin.qq.com/kfid/kfcf75cefbdc62946fa' }, + { title: '【重庆】', cityCode: 500100, serviceUrl: 'https://work.weixin.qq.com/kfid/kfcd7008f747d545f83' }, + { title: '【武汉】', cityCode: 420100, serviceUrl: 'https://work.weixin.qq.com/kfid/kfc047c94f8c709b395' }, + { title: '【厦门】', cityCode: 350200, serviceUrl: 'https://work.weixin.qq.com/kfid/kfc2007a895cb48464b' }, + { title: '【西安】', cityCode: 610100, serviceUrl: 'https://work.weixin.qq.com/kfid/kfc34768971b7354220' }, + { title: '【合肥】', cityCode: 340100, serviceUrl: 'https://work.weixin.qq.com/kfid/kfc41c9785cc2035277' }, + { title: '【南京】', cityCode: 320100, serviceUrl: 'https://work.weixin.qq.com/kfid/kfcc6dc8d0a9692b70e' }, + { title: '【青岛】', cityCode: 370200, serviceUrl: 'https://work.weixin.qq.com/kfid/kfce8d7a68190f6a1d2' }, + { title: '【佛山】', cityCode: 440600, serviceUrl: 'https://work.weixin.qq.com/kfid/kfcfac1132df386fac8' }, + { title: '【东莞】', cityCode: 441900, serviceUrl: 'https://work.weixin.qq.com/kfid/kfcb2b0e39026f7dddc' }, + { title: '【苏州】', cityCode: 320500, serviceUrl: 'https://work.weixin.qq.com/kfid/kfc4642f90a6e3528ff' }, + { title: '【福州】', cityCode: 350100, serviceUrl: 'https://work.weixin.qq.com/kfid/kfc126483dedadde82b' }, + { title: '【泉州】', cityCode: 350500, serviceUrl: 'https://work.weixin.qq.com/kfid/kfc4c8c42b1a9337aaf' }, + { title: '【温州】', cityCode: 330300, serviceUrl: 'https://work.weixin.qq.com/kfid/kfcb0ea5f197a18b335' }, + { title: '【天津】', cityCode: 120100, serviceUrl: 'https://work.weixin.qq.com/kfid/kfcda46c23dade6f6a3' }, + { title: '【昆明】', cityCode: 530100, serviceUrl: 'https://work.weixin.qq.com/kfid/kfcf2aebcbf3d46d9cd' }, + { title: '【全国】', cityCode: 440300, serviceUrl: 'https://work.weixin.qq.com/kfid/kfcc60ac7b6420787a8' }, ]; diff --git a/src/fragments/profile/intention/index.tsx b/src/fragments/profile/intention/index.tsx index d80ef3a..3e21d98 100644 --- a/src/fragments/profile/intention/index.tsx +++ b/src/fragments/profile/intention/index.tsx @@ -12,8 +12,8 @@ import { EmployType, EMPLOY_TYPE_TITLE_MAP, FULL_PRICE_OPTIONS, PART_PRICE_OPTIO import { SalaryRange } from '@/types/job'; import { MaterialProfile } from '@/types/material'; import { logWithPrefix } from '@/utils/common'; -import { isFullTimePriceRequired, isPartTimePriceRequired } from '@/utils/job' -import { getCurrentCity } from '@/utils/location'; +import { isFullTimePriceRequired, isPartTimePriceRequired } from '@/utils/job'; +import { getCurrentCityCode } from '@/utils/location'; import { navigateTo } from '@/utils/route'; import './index.less'; @@ -76,9 +76,9 @@ function ProfileIntentionFragment(props: IProps, ref) { ); const handleClickAddCity = useCallback(() => { - const currentCity = getCurrentCity(); + const currentCityCode = getCurrentCityCode(); realtimeLogger.info('handleClickAddCity', OpenSource.AddIndentCity); - navigateTo(PageUrl.CitySearchProfile, { city: currentCity, source: OpenSource.AddIndentCity }); + navigateTo(PageUrl.CitySearchProfile, { city: currentCityCode, source: OpenSource.AddIndentCity }); }, []); const handleSelectCity = useCallback( @@ -98,10 +98,10 @@ function ProfileIntentionFragment(props: IProps, ref) { const handleEmployTypeChange = useCallback((value: EmployType) => { setEmployType(value); if (value === EmployType.Full) { - setPartSalary({ minSalary: 0, maxSalary: 0 }) + setPartSalary({ minSalary: 0, maxSalary: 0 }); } if (value === EmployType.Part) { - setFullSalary({ minSalary: 0, maxSalary: 0 }) + setFullSalary({ minSalary: 0, maxSalary: 0 }); } }, []); @@ -173,24 +173,26 @@ function ProfileIntentionFragment(props: IProps, ref) { - {isFullTimePriceRequired(employType) && - ( + {isFullTimePriceRequired(employType) && ( + - )} - {isPartTimePriceRequired(employType) && - ( + + )} + {isPartTimePriceRequired(employType) && ( + - )} + + )} diff --git a/src/hooks/use-config.tsx b/src/hooks/use-config.tsx index d037094..71ec5cb 100644 --- a/src/hooks/use-config.tsx +++ b/src/hooks/use-config.tsx @@ -48,7 +48,7 @@ const CompanyTabs: TabItemType[] = [ { type: PageType.BatchPublish, pagePath: PageUrl.UserBatchPublish, - text: '群代发', + text: '代招代发', }, ]; diff --git a/src/pages/search-city-profile/index.less b/src/pages/search-city-profile/index.less index ea36334..bb37cd3 100644 --- a/src/pages/search-city-profile/index.less +++ b/src/pages/search-city-profile/index.less @@ -1,123 +1,4 @@ @import '@/styles/variables.less'; .search-city-profile { - background: #FFF; - - &__position-title { - font-size: 24px; - color: @blColorG1; - padding: 0 24px; - margin-top: 18px; - } - - &__position-city { - font-size: 30px; - font-weight: bold; - color: @blColor; - padding: 0 24px; - margin-top: 18px; - } - - &__hot-city-title { - height: 48px; - font-size: 24px; - line-height: 48px; - padding: 0 24px; - color: #999; - background: #f2f5f7; - margin-top: 18px; - } - - &__hot-city-container { - display: flex; - flex-wrap: wrap; - justify-content: space-between; - align-content: space-between; - width: 630px; - padding: 12px 90px 26px 30px; - background: #FFFFFF; - } - - &__hot-city-item { - width: 140px; - height: 58px; - font-size: 28px; - line-height: 58px; - text-align: center; - border-radius: 58px; - border: 2px solid @blColorG1; - margin-top: 18px; - } - - &__indexes-list { - width: 100%; - /* 兼容 iOS < 11.2 */ - padding-bottom: constant(safe-area-inset-bottom); - /* 兼容 iOS >= 11.2 */ - padding-bottom: env(safe-area-inset-bottom); - } - - &__indexes-fragment {} - - &__indexes-anchor { - height: 48px; - font-size: 24px; - line-height: 48px; - padding: 0 24px; - color: @blColorG1; - background: #f2f5f7; - } - - &__indexes-cell { - position: relative; - font-size: 28px; - padding: 30px 24px; - color: @blColor; - - &::after { - content: ''; - position: absolute; - border-bottom: 1rpx solid #eaeef1; - transform: scaleY(0.5); - bottom: 0; - right: 0; - left: 24px; - } - } - - &__indexes-bar { - width: 44rpx; - display: flex; - flex-direction: column; - align-items: center; - justify-content: flex-start; - position: fixed; - right: 10px; - } - - &__indexes-bar-item { - font-size: 22px; - color: @blColor; - white-space: nowrap; - display: flex; - align-items: center; - justify-content: center; - } - - &__indexes-index-alert { - position: absolute; - z-index: 20; - width: 160px; - height: 160px; - left: 50%; - top: 50%; - margin-left: -80px; - margin-top: -80px; - border-radius: 80px; - text-align: center; - line-height: 160px; - font-size: 70px; - color: #FFFFFF; - background-color: rgba(0, 0, 0, 0.5); - } } diff --git a/src/pages/search-city-profile/index.tsx b/src/pages/search-city-profile/index.tsx index fff0b3f..fd525fc 100644 --- a/src/pages/search-city-profile/index.tsx +++ b/src/pages/search-city-profile/index.tsx @@ -1,130 +1,29 @@ -import { BaseEventOrig, InputProps, ScrollView } from '@tarojs/components'; import Taro, { useLoad } from '@tarojs/taro'; -import { Search } from '@taroify/core'; -import { useCallback, useEffect, useRef, useState } from 'react'; +import { useCallback, useRef, useState } from 'react'; +import SearchCity from '@/components/search-city'; import { EventName, OpenSource } from '@/constants/app'; -import { CITY_CODE_TO_NAME_MAP, CITY_INDEXES_LIST } from '@/constants/city'; import { logWithPrefix } from '@/utils/common'; import { getPageQuery, navigateBack } from '@/utils/route'; - import './index.less'; -interface Item { - cityCode: number | string; - cityName: string; - keyword: string; -} - const PREFIX = 'search-city-profile'; -const HOT_CITY = [ - { cityCode: 110100, cityName: '北京' }, - { cityCode: 310100, cityName: '上海' }, - { cityCode: 440100, cityName: '广州' }, - { cityCode: 440300, cityName: '深圳' }, - { cityCode: 330100, cityName: '杭州' }, - { cityCode: 430100, cityName: '长沙' }, - { cityCode: 420100, cityName: '武汉' }, - { cityCode: 350200, cityName: '厦门' }, - { cityCode: 610100, cityName: '西安' }, - { cityCode: 410100, cityName: '郑州' }, - { cityCode: 510100, cityName: '成都' }, - { cityCode: 340100, cityName: '合肥' }, -]; -const OFFSET_INDEX_SIZE = 2; + const log = logWithPrefix(PREFIX); const realtimeLogger = Taro.getRealtimeLogManager(); realtimeLogger.tag(PREFIX); -const useHeight = () => { - const [winHeight, setWinHeight] = useState(0); - const [indexItemHeight, setIndexItemHeight] = useState(0); - useEffect(() => { - const windowInfo = Taro.getWindowInfo(); - const windowHeight = windowInfo.windowHeight; - setWinHeight(windowHeight); - // 上下预留两个选项高度的空白 - setIndexItemHeight(Math.floor(windowHeight / (26 + OFFSET_INDEX_SIZE * 2))); - }, []); - - return [winHeight, indexItemHeight]; -}; - -export default function SearchCity() { - const [winHeight, indexItemHeight] = useHeight(); +export default function SearchCityProfilePage() { const [currentCity, setCurrentCity] = useState(''); - const [touchAnchor, setTouchAnchor] = useState(); - const [touchMoving, setTouchMoving] = useState(false); - const [searchResult, setSearchResult] = useState([]); const openSourceRef = useRef(OpenSource.None); - const showSearchList = searchResult.length > 0; - const handleSearchChange = useCallback((event: BaseEventOrig) => { - const value = event.detail.value; - log('handleSearchChange', value); - if (!value) { - setSearchResult([]); - return; - } - const result: Item[] = []; - CITY_INDEXES_LIST.forEach(obj => { - obj.data.forEach(city => { - if (city.keyword.includes(value.toLocaleUpperCase())) { - result.push({ ...city }); - } - }); - }); - setSearchResult(result); - }, []); - - const handleSelectCity = useCallback((e: React.MouseEvent) => { - const cityCode = e.currentTarget.dataset.code; + const handleSelectCity = useCallback(cityCode => { realtimeLogger.info('handleSelectCity openSource', openSourceRef.current); Taro.eventCenter.trigger(EventName.SELECT_CITY, { openSource: openSourceRef.current, cityCode: String(cityCode) }); navigateBack(1); }, []); - const handleTouchStart = useCallback( - (e: React.TouchEvent) => { - const pageY = e.touches[0].pageY; - const index = Math.floor(pageY / indexItemHeight) - OFFSET_INDEX_SIZE; - if (index < 0 || index >= CITY_INDEXES_LIST.length) { - return; - } - const item = CITY_INDEXES_LIST[index]; - if (item) { - setTouchMoving(true); - setTouchAnchor(item.letter); - } - }, - [indexItemHeight] - ); - - const handleTouchMove = useCallback( - (e: React.TouchEvent) => { - const pageY = e.touches[0].pageY; - const index = Math.floor(pageY / indexItemHeight) - OFFSET_INDEX_SIZE; - if (index < 0 || index >= CITY_INDEXES_LIST.length) { - return; - } - const item = CITY_INDEXES_LIST[index]; - item && setTouchAnchor(item.letter); - }, - [indexItemHeight] - ); - - const handleTouchEnd = useCallback((e: React.TouchEvent) => { - e.stopPropagation(); - setTouchMoving(false); - log('touch end'); - }, []); - - const handleClickAnchor = useCallback((anchor: string) => { - setTouchAnchor(anchor); - log('click anchor', anchor); - }, []); - useLoad(() => { const query = getPageQuery<{ city: string; source: OpenSource }>(); log('query', query); @@ -139,94 +38,7 @@ export default function SearchCity() { return (
- - - {showSearchList && ( -
- {searchResult.map(city => ( -
- {city.cityName} -
- ))} -
- )} - {!showSearchList && ( -
-
当前城市
-
{CITY_CODE_TO_NAME_MAP.get(currentCity)}
-
热门城市
-
- {HOT_CITY.map(city => ( -
- {city.cityName} -
- ))} -
-
- {CITY_INDEXES_LIST.map(item => { - return ( -
-
- {item.letter} -
- {item.data.map(city => ( -
- {city.cityName} -
- ))} -
- ); - })} -
-
- )} -
-
- {!showSearchList && ( -
- {CITY_INDEXES_LIST.map(item => { - return ( -
handleClickAnchor(item.letter)} - > - {item.letter} -
- ); - })} -
- )} - {touchAnchor && touchMoving &&
{touchAnchor}
} -
+
); } diff --git a/src/pages/search-city/index.less b/src/pages/search-city/index.less index 537c4bb..015f9d7 100644 --- a/src/pages/search-city/index.less +++ b/src/pages/search-city/index.less @@ -1,123 +1,4 @@ @import '@/styles/variables.less'; -.search-city { - background: #FFF; - - &__position-title { - font-size: 24px; - color: @blColorG1; - padding: 0 24px; - margin-top: 18px; - } - - &__position-city { - font-size: 30px; - font-weight: bold; - color: @blColor; - padding: 0 24px; - margin-top: 18px; - } - - &__hot-city-title { - height: 48px; - font-size: 24px; - line-height: 48px; - padding: 0 24px; - color: #999; - background: #f2f5f7; - margin-top: 18px; - } - - &__hot-city-container { - display: flex; - flex-wrap: wrap; - justify-content: space-between; - align-content: space-between; - width: 630px; - padding: 12px 90px 26px 30px; - background: #FFFFFF; - } - - &__hot-city-item { - width: 140px; - height: 58px; - font-size: 28px; - line-height: 58px; - text-align: center; - border-radius: 58px; - border: 2px solid @blColorG1; - margin-top: 18px; - } - - &__indexes-list { - width: 100%; - /* 兼容 iOS < 11.2 */ - padding-bottom: constant(safe-area-inset-bottom); - /* 兼容 iOS >= 11.2 */ - padding-bottom: env(safe-area-inset-bottom); - } - - &__indexes-fragment {} - - &__indexes-anchor { - height: 48px; - font-size: 24px; - line-height: 48px; - padding: 0 24px; - color: @blColorG1; - background: #f2f5f7; - } - - &__indexes-cell { - position: relative; - font-size: 28px; - padding: 30px 24px; - color: @blColor; - - &::after { - content: ''; - position: absolute; - border-bottom: 1rpx solid #eaeef1; - transform: scaleY(0.5); - bottom: 0; - right: 0; - left: 24px; - } - } - - &__indexes-bar { - width: 44rpx; - display: flex; - flex-direction: column; - align-items: center; - justify-content: flex-start; - position: fixed; - right: 10px; - } - - &__indexes-bar-item { - font-size: 22px; - color: @blColor; - white-space: nowrap; - display: flex; - align-items: center; - justify-content: center; - } - - &__indexes-index-alert { - position: absolute; - z-index: 20; - width: 160px; - height: 160px; - left: 50%; - top: 50%; - margin-left: -80px; - margin-top: -80px; - border-radius: 80px; - text-align: center; - line-height: 160px; - font-size: 70px; - color: #FFFFFF; - background-color: rgba(0, 0, 0, 0.5); - } -} \ No newline at end of file +.page.search-city { +} diff --git a/src/pages/search-city/index.tsx b/src/pages/search-city/index.tsx index 2c0a705..907dd73 100644 --- a/src/pages/search-city/index.tsx +++ b/src/pages/search-city/index.tsx @@ -1,129 +1,29 @@ -import { BaseEventOrig, InputProps, ScrollView } from '@tarojs/components'; import Taro, { useLoad } from '@tarojs/taro'; -import { Search } from '@taroify/core'; -import { useCallback, useEffect, useRef, useState } from 'react'; +import { useCallback, useRef, useState } from 'react'; +import SearchCity from '@/components/search-city'; import { EventName, OpenSource } from '@/constants/app'; -import { CITY_CODE_TO_NAME_MAP, CITY_INDEXES_LIST } from '@/constants/city'; import { logWithPrefix } from '@/utils/common'; import { getPageQuery, navigateBack } from '@/utils/route'; import './index.less'; -interface Item { - cityCode: number | string; - cityName: string; - keyword: string; -} +const PREFIX = 'page-search-city'; -const PREFIX = 'search-city'; -const HOT_CITY = [ - { cityCode: 110100, cityName: '北京' }, - { cityCode: 310100, cityName: '上海' }, - { cityCode: 440100, cityName: '广州' }, - { cityCode: 440300, cityName: '深圳' }, - { cityCode: 330100, cityName: '杭州' }, - { cityCode: 430100, cityName: '长沙' }, - { cityCode: 420100, cityName: '武汉' }, - { cityCode: 350200, cityName: '厦门' }, - { cityCode: 610100, cityName: '西安' }, - { cityCode: 410100, cityName: '郑州' }, - { cityCode: 510100, cityName: '成都' }, - { cityCode: 340100, cityName: '合肥' }, -]; -const OFFSET_INDEX_SIZE = 2; const log = logWithPrefix(PREFIX); const realtimeLogger = Taro.getRealtimeLogManager(); realtimeLogger.tag(PREFIX); -const useHeight = () => { - const [winHeight, setWinHeight] = useState(0); - const [indexItemHeight, setIndexItemHeight] = useState(0); - useEffect(() => { - const windowInfo = Taro.getWindowInfo(); - const windowHeight = windowInfo.windowHeight; - setWinHeight(windowHeight); - // 上下预留两个选项高度的空白 - setIndexItemHeight(Math.floor(windowHeight / (26 + OFFSET_INDEX_SIZE * 2))); - }, []); - - return [winHeight, indexItemHeight]; -}; - -export default function SearchCity() { - const [winHeight, indexItemHeight] = useHeight(); +export default function SearchCityPage() { const [currentCity, setCurrentCity] = useState(''); - const [touchAnchor, setTouchAnchor] = useState(); - const [touchMoving, setTouchMoving] = useState(false); - const [searchResult, setSearchResult] = useState([]); const openSourceRef = useRef(OpenSource.None); - const showSearchList = searchResult.length > 0; - const handleSearchChange = useCallback((event: BaseEventOrig) => { - const value = event.detail.value; - log('handleSearchChange', value); - if (!value) { - setSearchResult([]); - return; - } - const result: Item[] = []; - CITY_INDEXES_LIST.forEach(obj => { - obj.data.forEach(city => { - if (city.keyword.includes(value.toLocaleUpperCase())) { - result.push({ ...city }); - } - }); - }); - setSearchResult(result); - }, []); - - const handleSelectCity = useCallback((e: React.MouseEvent) => { - const cityCode = e.currentTarget.dataset.code; + const handleSelectCity = useCallback(cityCode => { Taro.eventCenter.trigger(EventName.SELECT_CITY, { openSource: openSourceRef.current, cityCode: String(cityCode) }); navigateBack(1); }, []); - const handleTouchStart = useCallback( - (e: React.TouchEvent) => { - const pageY = e.touches[0].pageY; - const index = Math.floor(pageY / indexItemHeight) - OFFSET_INDEX_SIZE; - if (index < 0 || index >= CITY_INDEXES_LIST.length) { - return; - } - const item = CITY_INDEXES_LIST[index]; - if (item) { - setTouchMoving(true); - setTouchAnchor(item.letter); - } - }, - [indexItemHeight] - ); - - const handleTouchMove = useCallback( - (e: React.TouchEvent) => { - const pageY = e.touches[0].pageY; - const index = Math.floor(pageY / indexItemHeight) - OFFSET_INDEX_SIZE; - if (index < 0 || index >= CITY_INDEXES_LIST.length) { - return; - } - const item = CITY_INDEXES_LIST[index]; - item && setTouchAnchor(item.letter); - }, - [indexItemHeight] - ); - - const handleTouchEnd = useCallback((e: React.TouchEvent) => { - e.stopPropagation(); - setTouchMoving(false); - log('touch end'); - }, []); - - const handleClickAnchor = useCallback((anchor: string) => { - setTouchAnchor(anchor); - log('click anchor', anchor); - }, []); - useLoad(() => { const query = getPageQuery<{ city: string; source: OpenSource }>(); log('query', query); @@ -138,94 +38,7 @@ export default function SearchCity() { return (
- - - {showSearchList && ( -
- {searchResult.map(city => ( -
- {city.cityName} -
- ))} -
- )} - {!showSearchList && ( -
-
当前城市
-
{CITY_CODE_TO_NAME_MAP.get(currentCity)}
-
热门城市
-
- {HOT_CITY.map(city => ( -
- {city.cityName} -
- ))} -
-
- {CITY_INDEXES_LIST.map(item => { - return ( -
-
- {item.letter} -
- {item.data.map(city => ( -
- {city.cityName} -
- ))} -
- ); - })} -
-
- )} -
-
- {!showSearchList && ( -
- {CITY_INDEXES_LIST.map(item => { - return ( -
handleClickAnchor(item.letter)} - > - {item.letter} -
- ); - })} -
- )} - {touchAnchor && touchMoving &&
{touchAnchor}
} -
+
); } diff --git a/src/pages/user-batch-publish/index.less b/src/pages/user-batch-publish/index.less index d5f1505..3aabde1 100644 --- a/src/pages/user-batch-publish/index.less +++ b/src/pages/user-batch-publish/index.less @@ -2,6 +2,8 @@ @import '@/styles/variables.less'; .page-biz-service { + padding-bottom: 200px; + &__tabs { --tabs-active-color: @blHighlightColor; --tabs-nav-background-color: #fff; @@ -48,5 +50,15 @@ padding-top: 20px; } } + + &-btn-group { + .flex-row(); + justify-content: center; + margin-top: 40px; + } + + &-btn { + .button(@height: 72px; @width: 384px; @fontSize: 28px; @fontWeight: 400; @borderRadius: 44px; @highlight: 0); + } } } diff --git a/src/pages/user-batch-publish/index.tsx b/src/pages/user-batch-publish/index.tsx index c62f7cb..951c1ee 100644 --- a/src/pages/user-batch-publish/index.tsx +++ b/src/pages/user-batch-publish/index.tsx @@ -1,20 +1,37 @@ -import { Tabs } from '@taroify/core'; +import { useShareAppMessage } from '@tarojs/taro'; +import { Button, Tabs } from '@taroify/core'; +import { useCallback } from 'react'; import HomePage from '@/components/home-page'; +import SearchCity from '@/components/search-city'; import UserBatchPublish from '@/components/user-batch-publish'; -import { logWithPrefix } from '@/utils/common'; - +import { GROUPS } from '@/constants/group'; +import { openCustomerServiceChat } from '@/utils/common'; +import { getCurrentCityCode } from '@/utils/location'; +import { getCommonShareMessage } from '@/utils/share'; import './index.less'; const PREFIX = 'page-biz-service'; -const log = logWithPrefix(PREFIX); export default function BizService() { + const handleOpenService = useCallback(() => { + openCustomerServiceChat('https://work.weixin.qq.com/kfid/kfc4fcf6b109b3771d7'); + }, []); + const handleSelectCity = useCallback(cityCode => { + const group = GROUPS.find(g => String(g.cityCode) === cityCode); + if (group) { + openCustomerServiceChat(group.serviceUrl); + } + }, []); + useShareAppMessage(() => getCommonShareMessage()); + return (
- + + + @@ -35,6 +52,11 @@ export default function BizService() {
我们在每个城市均有数量众多的主播群,少则几十个,多则上千个,有各种类型和层次的带货主播资源
+
+ +
diff --git a/src/types/group.ts b/src/types/group.ts index f6a52ea..e89ebf6 100644 --- a/src/types/group.ts +++ b/src/types/group.ts @@ -51,5 +51,6 @@ export interface GetGroupDetailsRequest { } export interface GroupItem { title: string; + cityCode: number; serviceUrl: string; } diff --git a/src/utils/location.ts b/src/utils/location.ts index 97a3c37..35e2f8d 100644 --- a/src/utils/location.ts +++ b/src/utils/location.ts @@ -33,9 +33,12 @@ export const calcDistance = (distance: number, fractionDigits = 2) => { } return '999km'; }; +export const getCurrentCityCode = () => { + return selectLocation(store.getState()).cityCode; +}; export const getCurrentCity = () => { - const cityCode = selectLocation(store.getState()).cityCode; + const cityCode = getCurrentCityCode(); return CITY_CODE_TO_NAME_MAP.get(cityCode) || ''; };