Compare commits
9 Commits
feat/juguo
...
3571740280
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3571740280 | ||
|
|
b6801cdde2 | ||
|
|
e1ebcd949b | ||
|
|
044e84a5b4 | ||
|
|
7833c2f552 | ||
|
|
9e4282545f | ||
| 2a9e8668a0 | |||
| 08092a89ab | |||
|
|
4f0cdad920 |
@@ -2,7 +2,7 @@
|
|||||||
"miniprogramRoot": "dist/",
|
"miniprogramRoot": "dist/",
|
||||||
"projectname": "playBallTogether",
|
"projectname": "playBallTogether",
|
||||||
"description": "playBallTogether",
|
"description": "playBallTogether",
|
||||||
"appid": "wx815b533167eb7b53",
|
"appid": "wx915ecf6c01bea4ec",
|
||||||
"setting": {
|
"setting": {
|
||||||
"urlCheck": true,
|
"urlCheck": true,
|
||||||
"es6": true,
|
"es6": true,
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ const ListCard: React.FC<ListCardProps> = ({
|
|||||||
className="image"
|
className="image"
|
||||||
mode="aspectFill"
|
mode="aspectFill"
|
||||||
lazyLoad
|
lazyLoad
|
||||||
defaultSource={`${OSS_BASE}/front/ball/images/publish-empty-card.svg`}
|
defaultSource={`${OSS_BASE}/front/ball/images/publish-empty-card.png`}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
.listLoadErrorImg {
|
.listLoadErrorImg {
|
||||||
width: 154px;
|
width: 154px;
|
||||||
height: 154px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.listLoadErrorText {
|
.listLoadErrorText {
|
||||||
|
|||||||
@@ -67,12 +67,6 @@ const NTRPEvaluatePopup = (props: NTRPEvaluatePopupProps, ref) => {
|
|||||||
const { updateUserInfo } = useUserActions();
|
const { updateUserInfo } = useUserActions();
|
||||||
const userInfo = useUserInfo();
|
const userInfo = useUserInfo();
|
||||||
const ntrpLevels = useNtrpLevels();
|
const ntrpLevels = useNtrpLevels();
|
||||||
const options = [
|
|
||||||
ntrpLevels.map((item) => ({
|
|
||||||
text: item,
|
|
||||||
value: item,
|
|
||||||
})),
|
|
||||||
];
|
|
||||||
const [evaCallback, setEvaCallback] = useState<EvaluateCallback>({
|
const [evaCallback, setEvaCallback] = useState<EvaluateCallback>({
|
||||||
type: "",
|
type: "",
|
||||||
next: () => {},
|
next: () => {},
|
||||||
@@ -171,7 +165,7 @@ const NTRPEvaluatePopup = (props: NTRPEvaluatePopupProps, ref) => {
|
|||||||
{visible && (
|
{visible && (
|
||||||
<Picker
|
<Picker
|
||||||
visible
|
visible
|
||||||
options={options}
|
options={ntrpLevels}
|
||||||
defaultValue={[ntrp]}
|
defaultValue={[ntrp]}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
console.log(val[0]);
|
console.log(val[0]);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { View, Text, Image } from "@tarojs/components";
|
|||||||
import Taro from "@tarojs/taro";
|
import Taro from "@tarojs/taro";
|
||||||
import { useUserInfo } from "@/store/userStore";
|
import { useUserInfo } from "@/store/userStore";
|
||||||
import {
|
import {
|
||||||
useEvaluate,
|
|
||||||
EvaluateCallback,
|
EvaluateCallback,
|
||||||
EvaluateScene,
|
EvaluateScene,
|
||||||
} from "@/store/evaluateStore";
|
} from "@/store/evaluateStore";
|
||||||
@@ -15,6 +14,7 @@ import styles from "./index.module.scss";
|
|||||||
import images from "@/config/images";
|
import images from "@/config/images";
|
||||||
import AiImportPopup from "@/publish_pages/publishBall/components/AiImportPopup";
|
import AiImportPopup from "@/publish_pages/publishBall/components/AiImportPopup";
|
||||||
import NTRPEvaluatePopup from "../NTRPEvaluatePopup";
|
import NTRPEvaluatePopup from "../NTRPEvaluatePopup";
|
||||||
|
import { useDictionaryStore } from "@/store/dictionaryStore";
|
||||||
|
|
||||||
export interface PublishMenuProps {
|
export interface PublishMenuProps {
|
||||||
onPersonalPublish?: () => void;
|
onPersonalPublish?: () => void;
|
||||||
@@ -30,6 +30,7 @@ const PublishMenu: React.FC<PublishMenuProps> = (props) => {
|
|||||||
area
|
area
|
||||||
} = useListState();
|
} = useListState();
|
||||||
|
|
||||||
|
const supportedCitiesList = useDictionaryStore((s) => s.getDictionaryValue('supported_cities')) || [];
|
||||||
|
|
||||||
// 使用 useEffect 监听 isVisible 变化,确保所有情况都能触发回调
|
// 使用 useEffect 监听 isVisible 变化,确保所有情况都能触发回调
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -67,10 +68,10 @@ const PublishMenu: React.FC<PublishMenuProps> = (props) => {
|
|||||||
};
|
};
|
||||||
const handleMenuItemClick = (type: "individual" | "group" | "ai") => {
|
const handleMenuItemClick = (type: "individual" | "group" | "ai") => {
|
||||||
const [_, address] = area;
|
const [_, address] = area;
|
||||||
if (address !== '上海市') {
|
if (!supportedCitiesList.includes(address)) {
|
||||||
(Taro as any).showModal({
|
(Taro as any).showModal({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
content: '仅上海地区开放,您可加入社群或切换城市',
|
content: '该城市尚未开放,您可加入社群或切换城市',
|
||||||
showCancel: false,
|
showCancel: false,
|
||||||
confirmText: '知道了'
|
confirmText: '知道了'
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export default {
|
|||||||
ICON_LIST_LOAD_ERROR: require("@/static/list/icon-load-error.svg"),
|
ICON_LIST_LOAD_ERROR: require("@/static/list/icon-load-error.svg"),
|
||||||
ICON_LIST_RELOAD: require("@/static/list/icon-reload.svg"),
|
ICON_LIST_RELOAD: require("@/static/list/icon-reload.svg"),
|
||||||
ICON_LIST_EMPTY: require("@/static/emptyStatus/publish-empty.png"),
|
ICON_LIST_EMPTY: require("@/static/emptyStatus/publish-empty.png"),
|
||||||
ICON_LIST_EMPTY_CARD: `${OSS_BASE}/front/ball/images/publish-empty-card.svg`,
|
ICON_LIST_EMPTY_CARD: `${OSS_BASE}/front/ball/images/publish-empty-card.png`,
|
||||||
ICON_LIST_SEARCH_SEARCH: require("@/static/search/icon-search.svg"),
|
ICON_LIST_SEARCH_SEARCH: require("@/static/search/icon-search.svg"),
|
||||||
ICON_LIST_SEARCH_BACK: require("@/static/search/icon-back.svg"),
|
ICON_LIST_SEARCH_BACK: require("@/static/search/icon-back.svg"),
|
||||||
ICON_LIST_SEARCH_CLEAR: require("@/static/search/icon-search-clear.svg"),
|
ICON_LIST_SEARCH_CLEAR: require("@/static/search/icon-search-clear.svg"),
|
||||||
|
|||||||
@@ -4,7 +4,11 @@ import ListLoadError from "@/components/ListLoadError";
|
|||||||
import ListCardSkeleton from "@/components/ListCardSkeleton";
|
import ListCardSkeleton from "@/components/ListCardSkeleton";
|
||||||
import { useReachBottom } from "@tarojs/taro";
|
import { useReachBottom } from "@tarojs/taro";
|
||||||
import Taro from "@tarojs/taro";
|
import Taro from "@tarojs/taro";
|
||||||
import { useUserInfo, useUserActions, useLastTestResult } from "@/store/userStore";
|
import {
|
||||||
|
useUserInfo,
|
||||||
|
useUserActions,
|
||||||
|
useLastTestResult,
|
||||||
|
} from "@/store/userStore";
|
||||||
import { NTRPTestEntryCard } from "@/components";
|
import { NTRPTestEntryCard } from "@/components";
|
||||||
import { EvaluateScene } from "@/store/evaluateStore";
|
import { EvaluateScene } from "@/store/evaluateStore";
|
||||||
import { waitForAuthInit } from "@/utils/authInit";
|
import { waitForAuthInit } from "@/utils/authInit";
|
||||||
@@ -46,7 +50,11 @@ const ListContainer = (props) => {
|
|||||||
const { fetchUserInfo, fetchLastTestResult } = useUserActions();
|
const { fetchUserInfo, fetchLastTestResult } = useUserActions();
|
||||||
// 使用全局状态中的测试结果,避免重复调用接口
|
// 使用全局状态中的测试结果,避免重复调用接口
|
||||||
const lastTestResult = useLastTestResult();
|
const lastTestResult = useLastTestResult();
|
||||||
const { bannerListImage, bannerDetailImage, bannerListIndex = 0 } = useDictionaryStore((s) => s.bannerDict) || {};
|
const {
|
||||||
|
bannerListImage,
|
||||||
|
bannerDetailImage,
|
||||||
|
bannerListIndex = 0,
|
||||||
|
} = useDictionaryStore((s) => s.bannerDict) || {};
|
||||||
useReachBottom(() => {
|
useReachBottom(() => {
|
||||||
// 加载更多方法
|
// 加载更多方法
|
||||||
if (loading) {
|
if (loading) {
|
||||||
@@ -102,7 +110,7 @@ const ListContainer = (props) => {
|
|||||||
// 先等待静默登录完成
|
// 先等待静默登录完成
|
||||||
await waitForAuthInit();
|
await waitForAuthInit();
|
||||||
// 然后再获取用户信息
|
// 然后再获取用户信息
|
||||||
const userInfoId = userInfo && 'id' in userInfo ? userInfo.id : null;
|
const userInfoId = userInfo && "id" in userInfo ? userInfo.id : null;
|
||||||
if (!userInfoId) {
|
if (!userInfoId) {
|
||||||
await fetchUserInfo();
|
await fetchUserInfo();
|
||||||
return; // 等待下一次 useEffect 触发(此时 userInfo.id 已有值)
|
return; // 等待下一次 useEffect 触发(此时 userInfo.id 已有值)
|
||||||
@@ -113,7 +121,13 @@ const ListContainer = (props) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
init();
|
init();
|
||||||
}, [evaluateFlag, enableHomeCards, userInfo, lastTestResult, fetchLastTestResult]);
|
}, [
|
||||||
|
evaluateFlag,
|
||||||
|
enableHomeCards,
|
||||||
|
userInfo,
|
||||||
|
lastTestResult,
|
||||||
|
fetchLastTestResult,
|
||||||
|
]);
|
||||||
|
|
||||||
// 从全局状态中获取测试状态
|
// 从全局状态中获取测试状态
|
||||||
const hasTestInLastMonth = lastTestResult?.has_test_in_last_month || false;
|
const hasTestInLastMonth = lastTestResult?.has_test_in_last_month || false;
|
||||||
@@ -144,7 +158,11 @@ const ListContainer = (props) => {
|
|||||||
const idx = Number(bannerListIndex);
|
const idx = Number(bannerListIndex);
|
||||||
return [
|
return [
|
||||||
...list.slice(0, idx),
|
...list.slice(0, idx),
|
||||||
{ type: "banner", banner_image_url: bannerListImage, banner_detail_url: bannerDetailImage },
|
{
|
||||||
|
type: "banner",
|
||||||
|
banner_image_url: bannerListImage,
|
||||||
|
banner_detail_url: bannerDetailImage,
|
||||||
|
},
|
||||||
...list.slice(idx),
|
...list.slice(idx),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -153,7 +171,9 @@ const ListContainer = (props) => {
|
|||||||
function insertEvaluateCard(list) {
|
function insertEvaluateCard(list) {
|
||||||
if (!list || !Array.isArray(list)) return insertBannerCard(list ?? []);
|
if (!list || !Array.isArray(list)) return insertBannerCard(list ?? []);
|
||||||
|
|
||||||
const limitedList = shouldLimitByShowNumber ? list.slice(0, showNumber) : list;
|
const limitedList = shouldLimitByShowNumber
|
||||||
|
? list.slice(0, showNumber)
|
||||||
|
: list;
|
||||||
|
|
||||||
if (!evaluateFlag || hasTestInLastMonth) {
|
if (!evaluateFlag || hasTestInLastMonth) {
|
||||||
return insertBannerCard(limitedList);
|
return insertBannerCard(limitedList);
|
||||||
@@ -170,7 +190,16 @@ const ListContainer = (props) => {
|
|||||||
|
|
||||||
const memoizedList = useMemo(
|
const memoizedList = useMemo(
|
||||||
() => (enableHomeCards ? insertEvaluateCard(data) : data),
|
() => (enableHomeCards ? insertEvaluateCard(data) : data),
|
||||||
[enableHomeCards, evaluateFlag, data, hasTestInLastMonth, showNumber, bannerListImage, bannerDetailImage, bannerListIndex]
|
[
|
||||||
|
enableHomeCards,
|
||||||
|
evaluateFlag,
|
||||||
|
data,
|
||||||
|
hasTestInLastMonth,
|
||||||
|
showNumber,
|
||||||
|
bannerListImage,
|
||||||
|
bannerDetailImage,
|
||||||
|
bannerListIndex,
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
// 渲染 banner 卡片
|
// 渲染 banner 卡片
|
||||||
@@ -185,7 +214,9 @@ const ListContainer = (props) => {
|
|||||||
const target = item.banner_detail_url;
|
const target = item.banner_detail_url;
|
||||||
if (target) {
|
if (target) {
|
||||||
(Taro as any).navigateTo({
|
(Taro as any).navigateTo({
|
||||||
url: `/other_pages/bannerDetail/index?img=${encodeURIComponent(target)}`,
|
url: `/other_pages/bannerDetail/index?img=${encodeURIComponent(
|
||||||
|
target
|
||||||
|
)}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
@@ -198,8 +229,7 @@ const ListContainer = (props) => {
|
|||||||
backgroundPosition: "center",
|
backgroundPosition: "center",
|
||||||
backgroundRepeat: "no-repeat",
|
backgroundRepeat: "no-repeat",
|
||||||
}}
|
}}
|
||||||
>
|
></View>
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -233,7 +263,10 @@ const ListContainer = (props) => {
|
|||||||
}
|
}
|
||||||
if (enableHomeCards && match?.type === "evaluateCard") {
|
if (enableHomeCards && match?.type === "evaluateCard") {
|
||||||
return (
|
return (
|
||||||
<NTRPTestEntryCard key={`evaluate-${index}`} type={EvaluateScene.list} />
|
<NTRPTestEntryCard
|
||||||
|
key={`evaluate-${index}`}
|
||||||
|
type={EvaluateScene.list}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return <ListCard key={match?.id || index} {...match} />;
|
return <ListCard key={match?.id || index} {...match} />;
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ const ListPageContent: React.FC<ListPageContentProps> = ({
|
|||||||
} = store;
|
} = store;
|
||||||
|
|
||||||
const supportedCitiesList = useDictionaryStore((s) => s.getDictionaryValue('supported_cities', ['上海市'])) || [];
|
const supportedCitiesList = useDictionaryStore((s) => s.getDictionaryValue('supported_cities', ['上海市'])) || [];
|
||||||
|
// 首页是否展示二维码,由 getDictionaryManyKey 的 show_home_qrcode 控制,默认 true 保持原样
|
||||||
|
const showHomeQrcode = useDictionaryStore((s) => s.getDictionaryValue('show_home_qrcode', true));
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isShowFilterPopup,
|
isShowFilterPopup,
|
||||||
@@ -227,18 +229,16 @@ const ListPageContent: React.FC<ListPageContentProps> = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 分批异步执行初始化操作,避免阻塞首屏渲染
|
// 分批异步执行初始化操作,避免阻塞首屏渲染
|
||||||
// 1. 立即执行:获取城市、二维码和行政区列表(轻量操作)
|
|
||||||
getCities();
|
getCities();
|
||||||
getCityQrCode();
|
if (showHomeQrcode) getCityQrCode();
|
||||||
getDistricts(); // 新增:获取行政区列表
|
getDistricts();
|
||||||
|
|
||||||
// 只有当页面激活时才加载位置和列表数据
|
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
getLocation().catch((error) => {
|
getLocation().catch((error) => {
|
||||||
console.error('获取位置信息失败:', error);
|
console.error('获取位置信息失败:', error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [isActive]);
|
}, [isActive, showHomeQrcode]);
|
||||||
|
|
||||||
// 记录上一次的城市,用于检测城市变化
|
// 记录上一次的城市,用于检测城市变化
|
||||||
const prevAreaRef = useRef<[string, string] | null>(null);
|
const prevAreaRef = useRef<[string, string] | null>(null);
|
||||||
@@ -537,7 +537,13 @@ const ListPageContent: React.FC<ListPageContentProps> = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{shouldShowNoGames ? (
|
{shouldShowNoGames ? (
|
||||||
renderCityQrcode()
|
showHomeQrcode ? (
|
||||||
|
renderCityQrcode()
|
||||||
|
) : (
|
||||||
|
<View className={styles.cqContainer}>
|
||||||
|
<Text>当前城市暂无球局,敬请期待</Text>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
) : (
|
) : (
|
||||||
<View ref={scrollContextRef}>
|
<View ref={scrollContextRef}>
|
||||||
<View className={styles.listPage} style={{ paddingTop: totalHeight }}>
|
<View className={styles.listPage} style={{ paddingTop: totalHeight }}>
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import { EvaluateScene } from "@/store/evaluateStore";
|
|||||||
import { useUserInfo, useUserActions } from "@/store/userStore";
|
import { useUserInfo, useUserActions } from "@/store/userStore";
|
||||||
import { usePickerOption } from "@/store/pickerOptionsStore";
|
import { usePickerOption } from "@/store/pickerOptionsStore";
|
||||||
import { useGlobalState } from "@/store/global";
|
import { useGlobalState } from "@/store/global";
|
||||||
|
import { useListState } from "@/store/listStore";
|
||||||
|
import { useDictionaryStore } from "@/store/dictionaryStore";
|
||||||
|
|
||||||
interface MyselfPageContentProps {
|
interface MyselfPageContentProps {
|
||||||
isActive?: boolean;
|
isActive?: boolean;
|
||||||
@@ -41,6 +43,10 @@ const MyselfPageContent: React.FC<MyselfPageContentProps> = ({
|
|||||||
const [collapseProfile, setCollapseProfile] = useState(false);
|
const [collapseProfile, setCollapseProfile] = useState(false);
|
||||||
const [refreshing, setRefreshing] = useState(false);
|
const [refreshing, setRefreshing] = useState(false);
|
||||||
|
|
||||||
|
const { area } = useListState();
|
||||||
|
const supportedCitiesList =
|
||||||
|
useDictionaryStore((s) => s.getDictionaryValue("supported_cities")) || [];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
pickerOption.getCities();
|
pickerOption.getCities();
|
||||||
pickerOption.getProfessions();
|
pickerOption.getProfessions();
|
||||||
@@ -82,7 +88,6 @@ const MyselfPageContent: React.FC<MyselfPageContentProps> = ({
|
|||||||
console.log("notEndGames", notEndGames);
|
console.log("notEndGames", notEndGames);
|
||||||
|
|
||||||
return { notEndGames, finishedGames };
|
return { notEndGames, finishedGames };
|
||||||
|
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
@@ -100,7 +105,6 @@ const MyselfPageContent: React.FC<MyselfPageContentProps> = ({
|
|||||||
games_data = await UserService.get_participated_games(user_info.id);
|
games_data = await UserService.get_participated_games(user_info.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const sorted_games = games_data.sort((a, b) => {
|
const sorted_games = games_data.sort((a, b) => {
|
||||||
return (
|
return (
|
||||||
new Date(a.original_start_time.replace(/\s/, "T")).getTime() -
|
new Date(a.original_start_time.replace(/\s/, "T")).getTime() -
|
||||||
@@ -156,6 +160,16 @@ const MyselfPageContent: React.FC<MyselfPageContentProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const goPublish = () => {
|
const goPublish = () => {
|
||||||
|
const [_, address] = area;
|
||||||
|
if (!supportedCitiesList.includes(address)) {
|
||||||
|
(Taro as any).showModal({
|
||||||
|
title: "提示",
|
||||||
|
content: "该城市尚未开放,您可加入社群或切换城市",
|
||||||
|
showCancel: false,
|
||||||
|
confirmText: "知道了",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
(Taro as any).navigateTo({
|
(Taro as any).navigateTo({
|
||||||
url: "/publish_pages/publishBall/index",
|
url: "/publish_pages/publishBall/index",
|
||||||
});
|
});
|
||||||
@@ -258,15 +272,17 @@ const MyselfPageContent: React.FC<MyselfPageContentProps> = ({
|
|||||||
<View className={styles.gameTabsSection}>
|
<View className={styles.gameTabsSection}>
|
||||||
<View className={styles.tabContainer}>
|
<View className={styles.tabContainer}>
|
||||||
<View
|
<View
|
||||||
className={`${styles.tabItem} ${active_tab === "hosted" ? styles.active : ""
|
className={`${styles.tabItem} ${
|
||||||
}`}
|
active_tab === "hosted" ? styles.active : ""
|
||||||
|
}`}
|
||||||
onClick={() => setActiveTab("hosted")}
|
onClick={() => setActiveTab("hosted")}
|
||||||
>
|
>
|
||||||
<Text className={styles.tabText}>我主办的</Text>
|
<Text className={styles.tabText}>我主办的</Text>
|
||||||
</View>
|
</View>
|
||||||
<View
|
<View
|
||||||
className={`${styles.tabItem} ${active_tab === "participated" ? styles.active : ""
|
className={`${styles.tabItem} ${
|
||||||
}`}
|
active_tab === "participated" ? styles.active : ""
|
||||||
|
}`}
|
||||||
onClick={() => setActiveTab("participated")}
|
onClick={() => setActiveTab("participated")}
|
||||||
>
|
>
|
||||||
<Text className={styles.tabText}>我参与的</Text>
|
<Text className={styles.tabText}>我参与的</Text>
|
||||||
@@ -287,7 +303,7 @@ const MyselfPageContent: React.FC<MyselfPageContentProps> = ({
|
|||||||
btnImg="ICON_ADD"
|
btnImg="ICON_ADD"
|
||||||
reload={goPublish}
|
reload={goPublish}
|
||||||
isShowNoData={game_records.length === 0}
|
isShowNoData={game_records.length === 0}
|
||||||
loadMoreMatches={() => { }}
|
loadMoreMatches={() => {}}
|
||||||
collapse={true}
|
collapse={true}
|
||||||
style={{
|
style={{
|
||||||
paddingBottom: ended_game_records.length ? 0 : "90px",
|
paddingBottom: ended_game_records.length ? 0 : "90px",
|
||||||
@@ -313,7 +329,7 @@ const MyselfPageContent: React.FC<MyselfPageContentProps> = ({
|
|||||||
error={null}
|
error={null}
|
||||||
errorImg="ICON_LIST_EMPTY_CARD"
|
errorImg="ICON_LIST_EMPTY_CARD"
|
||||||
isShowNoData={ended_game_records.length === 0}
|
isShowNoData={ended_game_records.length === 0}
|
||||||
loadMoreMatches={() => { }}
|
loadMoreMatches={() => {}}
|
||||||
collapse={true}
|
collapse={true}
|
||||||
style={{ paddingBottom: "90px", overflow: "hidden" }}
|
style={{ paddingBottom: "90px", overflow: "hidden" }}
|
||||||
listLoadErrorWrapperHeight="fit-content"
|
listLoadErrorWrapperHeight="fit-content"
|
||||||
|
|||||||
@@ -166,18 +166,40 @@ const MainPage: React.FC = () => {
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
// 分享:首页、个人页均支持转发
|
// 分享:按 tab 用 map 对应文案与分享图
|
||||||
// 分享图:配置 OSS 地址 + 路径(不含 ? 后参数),首页用 share_home.png,个人页用 share_self.png
|
const share_config: Record<
|
||||||
|
TabType,
|
||||||
|
{ title: string; image_path: string; query: string }
|
||||||
|
> = {
|
||||||
|
list: {
|
||||||
|
title: "有你就有场,发现身边好球友和好球局",
|
||||||
|
image_path: "system/share_home.png",
|
||||||
|
query: "?tab=list",
|
||||||
|
},
|
||||||
|
personal: {
|
||||||
|
title: "快来有场,约我一起打网球~",
|
||||||
|
image_path: "system/share_self.png",
|
||||||
|
query: "?tab=personal",
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
title: "查看球友动态",
|
||||||
|
image_path: "system/share_home.png",
|
||||||
|
query: "?tab=message",
|
||||||
|
},
|
||||||
|
};
|
||||||
useShareAppMessage(() => {
|
useShareAppMessage(() => {
|
||||||
const isList = currentTab === "list";
|
const config = share_config[currentTab] ?? {
|
||||||
const isPersonal = currentTab === "personal";
|
title: "约球",
|
||||||
const title = isList ? "约球 - 发现身边的球局" : isPersonal ? "约球 - 我的约球" : "约球";
|
image_path: "system/share_home.png",
|
||||||
const image_path = isPersonal ? "system/share_self.png" : "system/share_home.png";
|
query: "",
|
||||||
const imageUrl = OSS_BASE ? `${OSS_BASE.replace(/\/$/, "")}/${image_path}` : "";
|
};
|
||||||
|
// const imageUrl = OSS_BASE
|
||||||
|
// ? `${OSS_BASE.replace(/\/$/, "")}/${config.image_path}`
|
||||||
|
// : "";
|
||||||
return {
|
return {
|
||||||
title,
|
title: config.title,
|
||||||
path: "/main_pages/index" + (isList ? "?tab=list" : isPersonal ? "?tab=personal" : ""),
|
path: "/main_pages/index" + config.query,
|
||||||
imageUrl: imageUrl,
|
// imageUrl,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,9 @@
|
|||||||
border-bottom: 0.5px solid rgba(0, 0, 0, 0.06);
|
border-bottom: 0.5px solid rgba(0, 0, 0, 0.06);
|
||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
color: #000;
|
color: #000;
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -57,7 +59,9 @@
|
|||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|
||||||
color: rgba(60, 60, 67, 0.6);
|
color: rgba(60, 60, 67, 0.6);
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -117,7 +121,9 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
background: #ff3b30;
|
background: #ff3b30;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "SF Compact Rounded";
|
font-family: "SF Compact Rounded";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
@@ -133,7 +139,9 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "SF Compact Rounded";
|
font-family: "SF Compact Rounded";
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -154,7 +162,9 @@
|
|||||||
|
|
||||||
.date {
|
.date {
|
||||||
color: #000;
|
color: #000;
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -164,7 +174,9 @@
|
|||||||
|
|
||||||
.venueTime {
|
.venueTime {
|
||||||
color: rgba(0, 0, 0, 0.8);
|
color: rgba(0, 0, 0, 0.8);
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -191,7 +203,9 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
color: rgba(0, 0, 0, 0.8);
|
color: rgba(0, 0, 0, 0.8);
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -235,7 +249,9 @@
|
|||||||
gap: 4px;
|
gap: 4px;
|
||||||
color: #000;
|
color: #000;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -251,7 +267,9 @@
|
|||||||
&Address {
|
&Address {
|
||||||
color: rgba(0, 0, 0, 0.8);
|
color: rgba(0, 0, 0, 0.8);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -270,7 +288,9 @@
|
|||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
color: var(--Labels-Secondary, rgba(60, 60, 67, 0.6));
|
color: var(--Labels-Secondary, rgba(60, 60, 67, 0.6));
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -307,7 +327,9 @@
|
|||||||
|
|
||||||
& > .buttonText {
|
& > .buttonText {
|
||||||
color: #000;
|
color: #000;
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -347,7 +369,9 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
color: #000;
|
color: #000;
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -373,7 +397,9 @@
|
|||||||
width: 120px;
|
width: 120px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
color: rgba(60, 60, 67, 0.6);
|
color: rgba(60, 60, 67, 0.6);
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -383,7 +409,9 @@
|
|||||||
|
|
||||||
.content {
|
.content {
|
||||||
color: #000;
|
color: #000;
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -400,9 +428,10 @@
|
|||||||
|
|
||||||
.orderNo {
|
.orderNo {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
flex-direction: column;
|
||||||
align-items: center;
|
justify-content: center;
|
||||||
gap: 8px;
|
align-items: flex-end;
|
||||||
|
gap: 0px;
|
||||||
|
|
||||||
.copy {
|
.copy {
|
||||||
color: #007aff;
|
color: #007aff;
|
||||||
@@ -421,7 +450,9 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
color: #000;
|
color: #000;
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -442,7 +473,9 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
color: #000;
|
color: #000;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -491,7 +524,9 @@
|
|||||||
&:nth-child(1) {
|
&:nth-child(1) {
|
||||||
color: #000;
|
color: #000;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -531,7 +566,9 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
color: #000;
|
color: #000;
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -567,7 +604,9 @@
|
|||||||
background: #000;
|
background: #000;
|
||||||
box-shadow: 0 8px 64px 0 rgba(0, 0, 0, 0.1);
|
box-shadow: 0 8px 64px 0 rgba(0, 0, 0, 0.1);
|
||||||
backdrop-filter: blur(16px);
|
backdrop-filter: blur(16px);
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -600,7 +639,9 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
// border: 0.5px solid rgba(0, 0, 0, 0.06);
|
// border: 0.5px solid rgba(0, 0, 0, 0.06);
|
||||||
color: #000;
|
color: #000;
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -626,7 +667,9 @@
|
|||||||
padding: 12px 15px;
|
padding: 12px 15px;
|
||||||
color: rgba(60, 60, 67, 0.6);
|
color: rgba(60, 60, 67, 0.6);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-feature-settings: "liga" off, "clig" off;
|
font-feature-settings:
|
||||||
|
"liga" off,
|
||||||
|
"clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ const OrderList = () => {
|
|||||||
>
|
>
|
||||||
<GeneralNavbar
|
<GeneralNavbar
|
||||||
title="球局订单"
|
title="球局订单"
|
||||||
backgroundColor="transparent"
|
backgroundColor="#ffffff"
|
||||||
titleClassName={styles.titleClassName}
|
titleClassName={styles.titleClassName}
|
||||||
className={styles.navbar}
|
className={styles.navbar}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ const StadiumDetail = forwardRef<StadiumDetailRef, StadiumDetailProps>(({
|
|||||||
<View className='stadium-item-right'>
|
<View className='stadium-item-right'>
|
||||||
<View className='stadium-name'>{formData.name}</View>
|
<View className='stadium-name'>{formData.name}</View>
|
||||||
<View className='stadium-address'>
|
<View className='stadium-address'>
|
||||||
<Text>{calculateDistance(formData.istance || null)} · </Text>
|
<Text>{calculateDistance(formData.istance || null) + ' · '}</Text>
|
||||||
<Text>{formData.address}</Text>
|
<Text>{formData.address}</Text>
|
||||||
<Image src={images.ICON_ARRORW_SMALL} className='stadium-map-icon' />
|
<Image src={images.ICON_ARRORW_SMALL} className='stadium-map-icon' />
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -35,17 +35,22 @@ export const useDictionaryStore = create<DictionaryState>()((set, get) => ({
|
|||||||
set({ isLoading: true, error: null })
|
set({ isLoading: true, error: null })
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const keys = 'publishing_requirements,court_type,court_surface,supplementary_information,game_play,fabu_tip,supported_cities,bannerListImage,bannerDetailImage,bannerListIndex';
|
const keys = 'publishing_requirements,court_type,court_surface,supplementary_information,game_play,fabu_tip,supported_cities,show_home_qrcode,bannerListImage,bannerDetailImage,bannerListIndex';
|
||||||
const response = await commonApi.getDictionaryManyKey(keys)
|
const response = await commonApi.getDictionaryManyKey(keys)
|
||||||
|
|
||||||
if (response.code === 0 && response.data) {
|
if (response.code === 0 && response.data) {
|
||||||
const dictionaryData = {};
|
const dictionaryData: DictionaryData = {};
|
||||||
keys.split(',').forEach(key => {
|
keys.split(',').forEach(key => {
|
||||||
const list = response.data[key];
|
const raw = response.data[key];
|
||||||
|
// 单值配置:首页是否展示二维码(1/0 或 true/false)
|
||||||
|
if (key === 'show_home_qrcode') {
|
||||||
|
dictionaryData[key] = raw === '1' || raw === 1 || raw === true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
// supported_cities 格式如 "上海市||北京市",用 || 分割
|
// supported_cities 格式如 "上海市||北京市",用 || 分割
|
||||||
const listData = key === 'supported_cities'
|
const listData = key === 'supported_cities'
|
||||||
? (list ? String(list).split('||').map((s) => s.trim()).filter(Boolean) : [])
|
? (raw ? String(raw).split('||').map((s) => s.trim()).filter(Boolean) : [])
|
||||||
: (list ? list.split('|') : []);
|
: (raw ? String(raw).split('|') : []);
|
||||||
dictionaryData[key] = listData;
|
dictionaryData[key] = listData;
|
||||||
})
|
})
|
||||||
set({
|
set({
|
||||||
|
|||||||
@@ -500,6 +500,7 @@ const WalletPage: React.FC = () => {
|
|||||||
{/* 顶部导航栏 */}
|
{/* 顶部导航栏 */}
|
||||||
<GeneralNavbar
|
<GeneralNavbar
|
||||||
title={pageTitle}
|
title={pageTitle}
|
||||||
|
backgroundColor="#ffffff"
|
||||||
showBack={true}
|
showBack={true}
|
||||||
showAvatar={false}
|
showAvatar={false}
|
||||||
onBack={() => {
|
onBack={() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user