Compare commits
4 Commits
05aa820466
...
feat/juguo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99c8026f61 | ||
| 05966b2acb | |||
|
|
4cf2b959b5 | ||
|
|
43610dcf99 |
@@ -52,7 +52,7 @@ const PopupPicker = ({
|
||||
ntrpTested,
|
||||
}: PickerProps) => {
|
||||
const [defaultValue, setDefaultValue] = useState<(string | number)[]>([]);
|
||||
const [defaultOptions, setDefaultOptions] = useState<PickerOption[][]>([]);
|
||||
const [defaultOptions, setDefaultOptions] = useState<PickerOption[][]>([...options]);
|
||||
const [pickerCurrentValue, setPickerCurrentValue] =
|
||||
useState<(string | number)[]>(value);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
useUserActions,
|
||||
useNicknameChangeStatus,
|
||||
useLastTestResult,
|
||||
useUserInfo,
|
||||
} from "@/store/userStore";
|
||||
import { UserInfoType } from "@/services/userService";
|
||||
import {
|
||||
@@ -73,7 +74,6 @@ const on_edit = () => {
|
||||
// 用户信息卡片组件
|
||||
const UserInfoCardComponent: React.FC<UserInfoCardProps> = ({
|
||||
editable = true,
|
||||
user_info,
|
||||
is_current_user,
|
||||
is_following = false,
|
||||
collapseProfile,
|
||||
@@ -84,6 +84,8 @@ const UserInfoCardComponent: React.FC<UserInfoCardProps> = ({
|
||||
set_user_info,
|
||||
onTab,
|
||||
}) => {
|
||||
|
||||
const user_info = useUserInfo();
|
||||
const nickname_change_status = useNicknameChangeStatus();
|
||||
const { setShowGuideBar } = useGlobalState();
|
||||
const { updateUserInfo, updateNickname, fetchLastTestResult } =
|
||||
@@ -122,11 +124,15 @@ const UserInfoCardComponent: React.FC<UserInfoCardProps> = ({
|
||||
useState(false);
|
||||
|
||||
// 表单状态
|
||||
const [form_data, set_form_data] = useState<Partial<UserInfoType>>({});
|
||||
const [form_data, set_form_data] = useState<Partial<UserInfoType>>({ ...user_info });
|
||||
|
||||
useDidShow(() => {
|
||||
// useDidShow(() => {
|
||||
// set_form_data({ ...user_info });
|
||||
// });
|
||||
|
||||
useEffect(() => {
|
||||
set_form_data({ ...user_info });
|
||||
});
|
||||
}, [user_info])
|
||||
|
||||
useEffect(() => {
|
||||
const visibles = [
|
||||
@@ -372,7 +378,6 @@ const UserInfoCardComponent: React.FC<UserInfoCardProps> = ({
|
||||
urls: [url],
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<View className="user_info_card">
|
||||
{/* 头像和基本信息 */}
|
||||
@@ -413,11 +418,11 @@ const UserInfoCardComponent: React.FC<UserInfoCardProps> = ({
|
||||
<View className="stats_section">
|
||||
<View
|
||||
className="stats_container"
|
||||
// style={{
|
||||
// marginBottom: `${
|
||||
// collapseProfile && setMarginBottom ? "16px" : "unset"
|
||||
// }`,
|
||||
// }}
|
||||
// style={{
|
||||
// marginBottom: `${
|
||||
// collapseProfile && setMarginBottom ? "16px" : "unset"
|
||||
// }`,
|
||||
// }}
|
||||
>
|
||||
<View
|
||||
className="stat_item clickable"
|
||||
@@ -650,16 +655,16 @@ const UserInfoCardComponent: React.FC<UserInfoCardProps> = ({
|
||||
<PopupPicker
|
||||
showHeader={true}
|
||||
title="选择性别"
|
||||
options={[
|
||||
options={
|
||||
[
|
||||
{ text: "男", value: "0" },
|
||||
{ text: "女", value: "1" },
|
||||
{ text: "保密", value: "2" },
|
||||
],
|
||||
]}
|
||||
]
|
||||
}
|
||||
visible={gender_picker_visible}
|
||||
setvisible={setGenderPickerVisible}
|
||||
value={form_data.gender === "" ? ["0"] : [form_data.gender]}
|
||||
value={!form_data.gender ? ["0"] : [form_data.gender]}
|
||||
onChange={handle_gender_change}
|
||||
/>
|
||||
)}
|
||||
@@ -868,9 +873,8 @@ export const GameTabs: React.FC<GameTabsProps> = ({
|
||||
<Text className="tab_text">{hosted_text}</Text>
|
||||
</View>
|
||||
<View
|
||||
className={`tab_item ${
|
||||
active_tab === "participated" ? "active" : ""
|
||||
}`}
|
||||
className={`tab_item ${active_tab === "participated" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => on_tab_change("participated")}
|
||||
>
|
||||
<Text className="tab_text">{participated_text}</Text>
|
||||
|
||||
@@ -132,40 +132,39 @@ const ListContainer = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
// 插入 banner 卡片
|
||||
// showNumber 为 0 表示尚未同步,不参与截断;截断时只限制「数据条数」,插卡不占数据条数
|
||||
const shouldLimitByShowNumber = showNumber > 0;
|
||||
|
||||
// 插入 banner 卡片(在 bannerListIndex 位置插入,不替换数据)
|
||||
function insertBannerCard(list) {
|
||||
if (!bannerListImage) return list;
|
||||
if (!list || !Array.isArray(list)) return list ?? [];
|
||||
if (!list || !Array.isArray(list)) {
|
||||
list = [];
|
||||
}
|
||||
const idx = Number(bannerListIndex);
|
||||
return [
|
||||
...list.slice(0, Number(bannerListIndex)),
|
||||
...list.slice(0, idx),
|
||||
{ type: "banner", banner_image_url: bannerListImage, banner_detail_url: bannerDetailImage },
|
||||
...list.slice(Number(bannerListIndex))
|
||||
...list.slice(idx),
|
||||
];
|
||||
}
|
||||
|
||||
// 对于没有ntrp等级的用户每个月展示一次, 插在第二个位置后面
|
||||
// insertBannerCard 需在最后统一执行,否则前面分支直接 return 时 banner 不会被插入
|
||||
// 对于没有 ntrp 等级的用户每个月展示一次,插在第 2 条数据后面;插卡是插入不替换,保留全部 showNumber 条数据
|
||||
function insertEvaluateCard(list) {
|
||||
let result: any[];
|
||||
if (!list || !Array.isArray(list)) return insertBannerCard(list ?? []);
|
||||
|
||||
if (!evaluateFlag) {
|
||||
result = showNumber !== undefined ? list.slice(0, showNumber) : list;
|
||||
} else if (!list || list.length === 0) {
|
||||
result = list;
|
||||
} else if (hasTestInLastMonth) {
|
||||
result = showNumber !== undefined ? list.slice(0, showNumber) : list;
|
||||
} else if (list.length <= 2) {
|
||||
result = [...list, { type: "evaluateCard" }];
|
||||
} else {
|
||||
const [item1, item2, ...rest] = list;
|
||||
result = [
|
||||
item1,
|
||||
item2,
|
||||
{ type: "evaluateCard" },
|
||||
...(showNumber !== undefined ? rest.slice(0, showNumber - 3) : rest),
|
||||
];
|
||||
const limitedList = shouldLimitByShowNumber ? list.slice(0, showNumber) : list;
|
||||
|
||||
if (!evaluateFlag || hasTestInLastMonth) {
|
||||
return insertBannerCard(limitedList);
|
||||
}
|
||||
|
||||
if (limitedList.length <= 2) {
|
||||
return insertBannerCard([...limitedList, { type: "evaluateCard" }]);
|
||||
}
|
||||
|
||||
const [item1, item2, ...rest] = limitedList;
|
||||
const result = [item1, item2, { type: "evaluateCard" }, ...rest];
|
||||
return insertBannerCard(result);
|
||||
}
|
||||
|
||||
@@ -204,10 +203,12 @@ const ListContainer = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
const showNoData = isShowNoData && !loading && memoizedList?.length === 0;
|
||||
|
||||
// 渲染列表
|
||||
const renderList = () => {
|
||||
// 请求数据为空
|
||||
if (isShowNoData) {
|
||||
if (showNoData) {
|
||||
return (
|
||||
<ListLoadError
|
||||
reload={reload}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '首页',
|
||||
navigationStyle: 'custom',
|
||||
navigationBarBackgroundColor: '#FAFAFA'
|
||||
})
|
||||
navigationBarTitleText: '首页',
|
||||
navigationStyle: 'custom',
|
||||
navigationBarBackgroundColor: '#FAFAFA',
|
||||
enableShareAppMessage: true,
|
||||
})
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import { View } from "@tarojs/components";
|
||||
import Taro from "@tarojs/taro";
|
||||
import Taro, { useRouter, useShareAppMessage } from "@tarojs/taro";
|
||||
import { OSS_BASE } from "@/config/api";
|
||||
import { wechat_auth_login, save_login_state } from "@/services/loginService";
|
||||
import { useUserActions } from "@/store/userStore";
|
||||
import { useGlobalState } from "@/store/global";
|
||||
@@ -18,7 +19,11 @@ import { useDictionaryStore } from "@/store/dictionaryStore";
|
||||
type TabType = "list" | "message" | "personal";
|
||||
|
||||
const MainPage: React.FC = () => {
|
||||
const [currentTab, setCurrentTab] = useState<TabType>("list");
|
||||
const { params } = useRouter();
|
||||
const [currentTab, setCurrentTab] = useState<TabType>(() => {
|
||||
const tab = params?.tab as TabType | undefined;
|
||||
return tab === "list" || tab === "message" || tab === "personal" ? tab : "list";
|
||||
});
|
||||
const [isPublishMenuVisible, setIsPublishMenuVisible] = useState(false);
|
||||
const [isDistanceFilterVisible, setIsDistanceFilterVisible] = useState(false);
|
||||
const [isCityPickerVisible, setIsCityPickerVisible] = useState(false);
|
||||
@@ -35,6 +40,14 @@ const MainPage: React.FC = () => {
|
||||
const { showGuideBar, guideBarZIndex, setShowGuideBar, setGuideBarZIndex } =
|
||||
useGlobalState();
|
||||
|
||||
// 从分享链接进入时根据 ?tab= 定位到对应 tab
|
||||
useEffect(() => {
|
||||
const tab = params?.tab as TabType | undefined;
|
||||
if (tab === "list" || tab === "message" || tab === "personal") {
|
||||
setCurrentTab(tab);
|
||||
}
|
||||
}, [params?.tab]);
|
||||
|
||||
// 初始化:自动微信授权并获取用户信息
|
||||
useEffect(() => {
|
||||
const init = async () => {
|
||||
@@ -153,6 +166,21 @@ const MainPage: React.FC = () => {
|
||||
[]
|
||||
);
|
||||
|
||||
// 分享:首页、个人页均支持转发
|
||||
// 分享图:配置 OSS 地址 + 路径(不含 ? 后参数),首页用 share_home.png,个人页用 share_self.png
|
||||
useShareAppMessage(() => {
|
||||
const isList = currentTab === "list";
|
||||
const isPersonal = currentTab === "personal";
|
||||
const title = isList ? "约球 - 发现身边的球局" : isPersonal ? "约球 - 我的约球" : "约球";
|
||||
const image_path = isPersonal ? "system/share_self.png" : "system/share_home.png";
|
||||
const imageUrl = OSS_BASE ? `${OSS_BASE.replace(/\/$/, "")}/${image_path}` : "";
|
||||
return {
|
||||
title,
|
||||
path: "/main_pages/index" + (isList ? "?tab=list" : isPersonal ? "?tab=personal" : ""),
|
||||
imageUrl: imageUrl,
|
||||
};
|
||||
});
|
||||
|
||||
// 滚动到顶部
|
||||
const scrollToTop = useCallback(() => {
|
||||
// 如果当前是列表页,触发列表页内部滚动
|
||||
|
||||
Reference in New Issue
Block a user