This commit is contained in:
张成
2025-11-14 23:31:04 +08:00
parent 1226350099
commit 3c4897508a
6 changed files with 51 additions and 29 deletions

View File

@@ -1,215 +0,0 @@
.listNavWrapper {
position: relative;
}
.listNavContainer {
display: flex;
align-items: center;
.listNavLine {
width: 1px;
height: 25px;
background-color: #0000000f;
}
.listNavLogo {
width: 60px;
height: 34px;
}
.listNavChange {
width: 12px;
height: 12px;
}
.listNavContentWrapper {
padding-left: 17px;
display: flex;
align-items: center;
gap: 8px;
}
.listNavCityWrapper {
line-height: 20px;
}
.listNavCity {
font-family: "PingFang SC"; // 根据设计稿设置字体
font-weight: 600;
font-size: 13px;
line-height: 20px; // 1.5384615384615385em ≈ 20px
letter-spacing: 0.38px; // 2.9230768863971415% of 13px
color: #000000; // 根据设计稿设置颜色
}
.infoWrapper {
line-height: 12px;
}
.listNavInfoWrapper {
font-family: "PingFang SC"; // 根据设计稿设置字体
font-weight: 400;
font-size: 10px;
line-height: 12px; // 1.2em
letter-spacing: 0.38px; // 3.7999999523162837% of 10px
color: rgba(60, 60, 67, 0.6); // 根据设计稿调整颜色 fill_9UGMHJ
}
}
.inputCustomerNavbarContainer {
padding-left: 17px;
display: flex;
align-items: center;
gap: 8px;
.logo {
width: 28px;
height: 16px;
}
.icon16 {
width: 16px;
height: 16px;
}
.navContent {
display: flex;
align-items: center;
gap: 4px; // 根据设计稿gap: 4px
flex: 1; // 占据剩余空间
height: max-content;
// padding-top: 5px;
}
.searchContainer {
display: flex;
align-items: center;
gap: 5.85px; // 根据设计稿调整间距5.853658676147461px
padding: 7.8px; // 根据设计稿调整内边距7.804878234863281px
flex: 1; // 响应式:占据剩余空间,适配不同屏幕
max-width: 55%; // 根据设计稿:最大宽度 240px大屏幕限制
min-width: 0; // 允许在小屏幕上缩小
height: 29.27px; // 根据设计稿调整高度29.27px
min-height: 29.27px; // 确保最小高度
box-sizing: border-box;
background: #fff;
border-radius: 999px; // 根据设计稿:完全圆角
border: 0.49px solid rgba(0, 0, 0, 0.06); // 根据设计稿调整边框0.4878048896789551px
// box-shadow: 0px 3.9px 46.83px 0px rgba(0, 0, 0, 0.08); // 根据设计稿调整阴影
font-family: "PingFang SC"; // 根据设计稿设置字体
font-size: 13.66px; // 根据设计稿调整字体大小13.658536911010742px
font-style: normal;
font-weight: 400;
line-height: 17.57px; // 1.2857142857142858em ≈ 17.57px
letter-spacing: -0.22px; // -1.6428571734045228% of 13.66px
.searchIcon {
flex-shrink: 0; // 防止图标被压缩
width: 15.61px; // 根据设计稿:图标尺寸 15.61x15.61
height: 15.61px;
}
.nut-input {
flex: 1; // 输入框占据剩余空间
padding: 0;
font-family: "PingFang SC";
font-size: 13.66px; // 根据设计稿调整字体大小
font-weight: 400;
line-height: 17.57px; // 1.2857142857142858em
letter-spacing: -0.22px; // -1.6428571734045228%
min-width: 0; // 允许输入框缩小
height: 100%; // 输入框高度填满容器
:global(.nut-input-inner) {
font-family: "PingFang SC";
font-size: 13.66px;
font-weight: 400;
line-height: 17.57px;
letter-spacing: -0.22px;
color: #000000; // 根据设计稿:文本颜色 fill_9WEVAH
height: 100%;
}
:global(.nut-input-placeholder) {
color: rgba(60, 60, 67, 0.6); // placeholder 颜色
font-size: 13.66px;
line-height: 17.57px;
letter-spacing: -0.22px;
}
}
}
}
.inputCustomerNavbarShowInput {
padding-left: 10px;
.logo {
width: 32px;
height: 32px;
}
}
.toggleElement {
/* 绝对定位使两个元素重叠 */
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
/* 启用硬件加速 */
will-change: opacity, transform;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
/* 优化过渡动画,使用更平滑的缓动函数和更短的动画时间 */
transition: opacity 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94),
transform 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
/* 第二个元素样式 */
.secondElement {
/* 初始状态:透明且稍微偏移 */
opacity: 0;
transform: translateY(-5px);
}
/* 隐藏状态 */
.hidden {
opacity: 0;
transform: translateY(-5px);
pointer-events: none;
}
/* 可见状态 */
.visible {
opacity: 1;
transform: translateY(0);
pointer-events: auto;
}
// 标题导航样式(用于"我的"页面等)
.titleNavContainer {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
.titleNavContent {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
padding: 0 16px;
.titleNavText {
font-family: "PingFang SC";
font-weight: 600;
font-size: 18px;
line-height: 1.4;
color: #333333;
text-align: center;
}
}
}

View File

@@ -1,232 +0,0 @@
import { useEffect, useState } from "react";
import { View, Text, Image } from "@tarojs/components";
import img from "@/config/images";
import { useGlobalState } from "@/store/global";
import { useUserInfo } from "@/store/userStore";
import { useListState } from "@/store/listStore";
import CustomNavbar from "@/components/CustomNavbar";
import { Input } from "@nutui/nutui-react-taro";
import Taro from "@tarojs/taro";
import "./index.scss";
import { getCurrentFullPath } from "@/utils";
import { CityPicker as PopupPicker } from "@/components/Picker";
interface IProps {
config?: {
showInput?: boolean;
inputLeftIcon?: string;
iconPath?: string;
leftIconClick?: () => void;
title?: string; // 显示标题(用于"我的"页面等)
showTitle?: boolean; // 是否显示标题模式
};
onCityPickerVisibleChange?: (visible: boolean) => void; // 城市选择器显示/隐藏回调
onScrollToTop?: () => void; // 滚动到顶部回调
}
function CityPicker(props) {
const { visible, setVisible, cities, area, setArea, onCityChange } = props;
console.log(cities, "cities");
const [value, setValue] = useState(area);
function onChange(value: any) {
console.log(value, "value");
setValue(value);
setArea(value);
// 切换城市时触发接口调用
if (onCityChange) {
onCityChange(value);
}
}
return (
visible && (
<PopupPicker
options={cities}
visible={visible}
setvisible={setVisible}
value={value}
onChange={onChange}
style={{ zIndex: 9991 }}
/>
)
);
}
const ListHeader = (props: IProps) => {
const { config, onCityPickerVisibleChange, onScrollToTop } = props;
const { showInput = false, inputLeftIcon, leftIconClick, title, showTitle = false } = config || {};
const { getLocationLoading, statusNavbarHeightInfo } = useGlobalState();
const { gamesNum, searchValue, cities, area, updateArea, getMatchesData, fetchGetGamesCount, refreshBothLists } = useListState();
const { navBarHeight } = statusNavbarHeightInfo;
const [cityPopupVisible, setCityPopupVisible] = useState(false);
// 监听城市选择器状态变化,通知父组件
useEffect(() => {
onCityPickerVisibleChange?.(cityPopupVisible);
}, [cityPopupVisible, onCityPickerVisibleChange]);
const userInfo = useUserInfo();
const province = (userInfo as any)?.province || "";
const city = (userInfo as any)?.city || "";
// const district = (userInfo as any)?.district || "";
useEffect(() => {
updateArea(["中国", province, city]);
}, [province, city]);
// const currentAddress = city + district;
const handleInputClick = () => {
const currentPagePath = getCurrentFullPath();
if (currentPagePath === "/game_pages/searchResult/index") {
Taro.navigateBack();
} else {
Taro.navigateTo({
url: "/game_pages/search/index",
});
}
};
// 点击logo
const handleLogoClick = () => {
// 如果当前在列表页,点击后页面回到顶部
if (getCurrentFullPath() === "/game_pages/list/index") {
// 使用父组件传递的滚动方法(适配 ScrollView
if (onScrollToTop) {
onScrollToTop();
} else {
// 降级方案:使用页面滚动(兼容旧版本)
Taro.pageScrollTo({
scrollTop: 0,
duration: 300,
});
}
}
Taro.redirectTo({
url: "game_pages/list/index", // 列表页
});
};
const handleInputLeftIconClick = () => {
if (leftIconClick) {
leftIconClick();
} else {
handleLogoClick();
}
};
const navbarStyle = {
height: `${navBarHeight}px`,
};
function handleToggleCity() {
setCityPopupVisible(true);
}
const area_city = area.at(-1);
// 处理城市切换
const handleCityChange = async (newArea: any) => {
// 切换城市后,同时更新两个列表接口获取数据
if (refreshBothLists) {
await refreshBothLists();
}
// 更新球局数量
if (fetchGetGamesCount) {
await fetchGetGamesCount();
}
};
return (
<CustomNavbar backgroundColor="#fafafa">
<View className="listNavWrapper">
{/* 标题模式(用于"我的"页面等) */}
{showTitle && (
<View className="titleNavContainer" style={navbarStyle}>
<View className="titleNavContent">
<Text className="titleNavText">{title || "我的"}</Text>
</View>
</View>
)}
{/* 首页logo 导航*/}
{!showTitle && (
<View
className={`listNavContainer toggleElement firstElement hidden
${!showInput ? "visible" : ""}`}
style={navbarStyle}
>
<View className="listNavContentWrapper">
{/* logo */}
<Image
src={img.ICON_LOGO}
className="listNavLogo"
onClick={handleLogoClick}
/>
<View className="listNavLine" />
<View className="listNavContent">
<View className="listNavCityWrapper" onClick={handleToggleCity}>
{/* 位置 */}
<Text className="listNavCity">{area_city}</Text>
{!getLocationLoading && area_city && (
<Image src={img.ICON_CHANGE} className="listNavChange" />
)}
</View>
<View className="listNavInfoWrapper">
<Text className="listNavInfo">{gamesNum}</Text>
</View>
</View>
</View>
</View>
)}
{/* 搜索导航 */}
{!showTitle && (
<View
className={`inputCustomerNavbarContainer toggleElement secondElement hidden ${
showInput && "visible"
} ${showInput ? "inputCustomerNavbarShowInput" : ""}`}
style={navbarStyle}
>
<View className="navContent">
{/* logo */}
<Image
src={inputLeftIcon || img.ICON_LIST_INPUT_LOGO}
className="logo"
onClick={handleInputLeftIconClick}
/>
{/* 搜索框 */}
<View className="searchContainer">
<Image
className="searchIcon icon16"
src={img.ICON_LIST_SEARCH_SEARCH}
/>
<Input
placeholder="搜索上海的球局和场地"
className="navbarInput"
clearable={false}
disabled
value={searchValue}
onClick={handleInputClick}
/>
</View>
</View>
</View>
)}
</View>
{cityPopupVisible && !showTitle && (
<CityPicker
visible={cityPopupVisible}
setVisible={setCityPopupVisible}
cities={cities}
area={area}
setArea={updateArea}
onCityChange={handleCityChange}
/>
)}
</CustomNavbar>
);
};
export default ListHeader;