From 5a10c73adf50e02e92659484499137b88b8afaaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=88=90?= Date: Sat, 7 Feb 2026 11:56:43 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=80=E5=A0=86=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ListCard/index.tsx | 2 +- src/components/Radar/index.tsx | 20 +++------ src/components/Radar/indexV2.tsx | 21 +++------ src/container/listContainer/index.tsx | 45 +++++++++---------- src/main_pages/index.tsx | 6 --- .../enable_notification/index.scss | 1 - src/other_pages/new_follow/index.tsx | 2 +- src/other_pages/ntrp-evaluate/index.tsx | 39 ++++++++-------- src/services/evaluateService.ts | 1 + src/store/dictionaryStore.ts | 33 +++++--------- 10 files changed, 65 insertions(+), 105 deletions(-) diff --git a/src/components/ListCard/index.tsx b/src/components/ListCard/index.tsx index c865790..c4b65c2 100644 --- a/src/components/ListCard/index.tsx +++ b/src/components/ListCard/index.tsx @@ -45,7 +45,7 @@ const ListCard: React.FC = ({ className="image" mode="aspectFill" lazyLoad - defaultSource="https://images.unsplash.com/photo-1554068865-24cecd4e34b8?w=200&h=200&fit=crop&crop=center" + defaultSource={require("@/static/emptyStatus/publish-empty-card.png")} /> ); }; diff --git a/src/components/Radar/index.tsx b/src/components/Radar/index.tsx index ca71305..c4a9fd9 100644 --- a/src/components/Radar/index.tsx +++ b/src/components/Radar/index.tsx @@ -89,25 +89,15 @@ const RadarChart: React.FC = forwardRef((props, ref) => { ctx.lineWidth = 1; ctx.stroke(); - // 标签 - const offset = 10; - const textX = center.x + (radius + offset) * Math.cos(angle); - const textY = center.y + (radius + offset) * Math.sin(angle); + // 标签:沿轴线外侧延伸,文字中心对齐轴线端点 + const labelOffset = 28; + const textX = center.x + (radius + labelOffset) * Math.cos(angle); + const textY = center.y + (radius + labelOffset) * Math.sin(angle); ctx.font = "12px sans-serif"; ctx.fillStyle = "#333"; ctx.textBaseline = "middle"; - - if ( - Math.abs(angle) < 0.01 || - Math.abs(Math.abs(angle) - Math.PI) < 0.01 - ) { - ctx.textAlign = "center"; - } else if (angle > -Math.PI / 2 && angle < Math.PI / 2) { - ctx.textAlign = "left"; - } else { - ctx.textAlign = "right"; - } + ctx.textAlign = "center"; ctx.fillText(label, textX, textY); }); diff --git a/src/components/Radar/indexV2.tsx b/src/components/Radar/indexV2.tsx index 9db6076..ab1e276 100644 --- a/src/components/Radar/indexV2.tsx +++ b/src/components/Radar/indexV2.tsx @@ -102,26 +102,15 @@ const RadarChartV2 = forwardRef((props, ref) ctx.lineWidth = 1 * (radarSize / 200); // 根据2倍图调整线宽 ctx.stroke(); - // 标签 - 文字显示在圆圈外面 - const offset = 10 * (radarSize / 200); // 文字距离圆圈的偏移量(2倍图) - const textX = center.x + (radius + offset) * Math.cos(angle); - const textY = center.y + (radius + offset) * Math.sin(angle); + // 标签:沿轴线外侧延伸,文字中心对齐轴线端点(与 index.tsx 一致) + const labelOffset = 28 * (radarSize / 200); // 文字距离圆圈的偏移量(2倍图) + const textX = center.x + (radius + labelOffset) * Math.cos(angle); + const textY = center.y + (radius + labelOffset) * Math.sin(angle); ctx.font = `${12 * (radarSize / 200)}px sans-serif`; // 根据2倍图调整字体大小 ctx.fillStyle = "#333"; ctx.textBaseline = "middle"; - - // 调整文字对齐方式 - if ( - Math.abs(angle) < 0.01 || - Math.abs(Math.abs(angle) - Math.PI) < 0.01 - ) { - ctx.textAlign = "center"; - } else if (angle > -Math.PI / 2 && angle < Math.PI / 2) { - ctx.textAlign = "left"; - } else { - ctx.textAlign = "right"; - } + ctx.textAlign = "center"; ctx.fillText(label, textX, textY); }); diff --git a/src/container/listContainer/index.tsx b/src/container/listContainer/index.tsx index 40b89b4..23b2647 100644 --- a/src/container/listContainer/index.tsx +++ b/src/container/listContainer/index.tsx @@ -134,6 +134,7 @@ const ListContainer = (props) => { // 插入 banner 卡片 function insertBannerCard(list) { if (!bannerListImage) return list; + if (!list || !Array.isArray(list)) return list ?? []; return [ ...list.slice(0, Number(bannerListIndex)), { type: "banner", banner_image_url: bannerListImage, banner_detail_url: bannerDetailImage }, @@ -142,33 +143,29 @@ const ListContainer = (props) => { } // 对于没有ntrp等级的用户每个月展示一次, 插在第二个位置后面 + // insertBannerCard 需在最后统一执行,否则前面分支直接 return 时 banner 不会被插入 function insertEvaluateCard(list) { - if (!evaluateFlag) - return showNumber !== undefined ? list.slice(0, showNumber) : list; - if (!list || list.length === 0) { - return list; - } - // 如果最近一个月有测试记录,则不插入 card - if (hasTestInLastMonth) { - return showNumber !== undefined ? list.slice(0, showNumber) : list; + let result: any[]; + + 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), + ]; } - if (list.length <= 2) { - return [...list, { type: "evaluateCard" }]; - } - const [item1, item2, ...rest] = list; - - let result = [ - item1, - item2, - { type: "evaluateCard" }, - ...(showNumber !== undefined ? rest.slice(0, showNumber - 3) : rest), - ]; - - if (bannerListImage) { - return insertBannerCard(result); - } - return result; + return insertBannerCard(result); } const memoizedList = useMemo( diff --git a/src/main_pages/index.tsx b/src/main_pages/index.tsx index b71b954..114d516 100644 --- a/src/main_pages/index.tsx +++ b/src/main_pages/index.tsx @@ -67,12 +67,6 @@ const MainPage: React.FC = () => { try { await fetchUserInfo(); await checkNicknameChangeStatus(); - // 启动时预取 Banner 字典(与业务无强依赖,失败不影响主流程) - try { - await useDictionaryStore.getState().fetchBannerDictionary(); - } catch (e) { - console.error("预取 Banner 字典失败:", e); - } } catch (error) { console.error("获取用户信息失败:", error); } diff --git a/src/other_pages/enable_notification/index.scss b/src/other_pages/enable_notification/index.scss index b18b4dc..b2e1ca5 100644 --- a/src/other_pages/enable_notification/index.scss +++ b/src/other_pages/enable_notification/index.scss @@ -12,7 +12,6 @@ align-items: center; flex: 1; position: relative; - overflow: hidden; } // 示例消息卡片区域 diff --git a/src/other_pages/new_follow/index.tsx b/src/other_pages/new_follow/index.tsx index 61eec71..c1932f9 100644 --- a/src/other_pages/new_follow/index.tsx +++ b/src/other_pages/new_follow/index.tsx @@ -193,7 +193,7 @@ const NewFollow = () => { handleUserClick(item.user_id)}> diff --git a/src/other_pages/ntrp-evaluate/index.tsx b/src/other_pages/ntrp-evaluate/index.tsx index 38cde35..33303e9 100644 --- a/src/other_pages/ntrp-evaluate/index.tsx +++ b/src/other_pages/ntrp-evaluate/index.tsx @@ -216,9 +216,8 @@ function Intro() { }); } Taro.redirectTo({ - url: `/other_pages/ntrp-evaluate/index?stage=${type}${ - type === StageType.RESULT ? `&id=${id}` : "" - }`, + url: `/other_pages/ntrp-evaluate/index?stage=${type}${type === StageType.RESULT ? `&id=${id}` : "" + }`, }); } @@ -539,18 +538,21 @@ function Result() { const res = await evaluateService.getTestResult({ record_id: Number(id) }); if (res.code === 0) { setResult(res.data); - // delay(1000); - setRadarData( - adjustRadarLabels( - Object.entries(res.data.radar_data.abilities).map(([key, value]) => [ - key, - Math.min( - 100, - Math.floor((value.current_score / value.max_score) * 100) - ), - ]) - ) - ); + + const sortOrder = res.data.sort || []; + const abilities = res.data.radar_data.abilities; + const sortedKeys = sortOrder.filter((k) => k in abilities); + const remainingKeys = Object.keys(abilities).filter((k) => !sortOrder.includes(k)); + const allKeys = [...sortedKeys, ...remainingKeys]; + let radarData: [string, number][] = allKeys.map((key) => [ + key, + Math.min( + 100, + Math.floor((abilities[key].current_score / abilities[key].max_score) * 100) + ), + ]); + // 直接使用接口 sort 顺序,不经过 adjustRadarLabels 重新排序 + setRadarData(radarData); updateUserLevel(res.data.record_id, res.data.ntrp_level); } } @@ -698,13 +700,12 @@ function Result() { } const currentPage = getCurrentFullPath(); Taro.redirectTo({ - url: `/login_pages/index/index${ - currentPage ? `?redirect=${encodeURIComponent(currentPage)}` : "" - }`, + url: `/login_pages/index/index${currentPage ? `?redirect=${encodeURIComponent(currentPage)}` : "" + }`, }); } - function handleGo() {} + function handleGo() { } return ( diff --git a/src/services/evaluateService.ts b/src/services/evaluateService.ts index dab032d..d7c3778 100644 --- a/src/services/evaluateService.ts +++ b/src/services/evaluateService.ts @@ -58,6 +58,7 @@ export interface TestResultData { level_img?: string; // 等级图片URL radar_data: RadarData; answers: Answer[]; + sort?: string[]; // 雷达图能力项排序,如 ["正手球质", "正手控制", ...] } // 单条测试记录 diff --git a/src/store/dictionaryStore.ts b/src/store/dictionaryStore.ts index 47a5e28..8f361d2 100644 --- a/src/store/dictionaryStore.ts +++ b/src/store/dictionaryStore.ts @@ -20,7 +20,6 @@ interface DictionaryState { bannerDetailImage: string bannerListIndex: string } | null - fetchBannerDictionary: () => Promise } // 创建字典Store @@ -36,7 +35,7 @@ export const useDictionaryStore = create()((set, get) => ({ set({ isLoading: true, error: null }) try { - const keys = 'publishing_requirements,court_type,court_surface,supplementary_information,game_play,fabu_tip,supported_cities'; + const keys = 'publishing_requirements,court_type,court_surface,supplementary_information,game_play,fabu_tip,supported_cities,bannerListImage,bannerDetailImage,bannerListIndex'; const response = await commonApi.getDictionaryManyKey(keys) if (response.code === 0 && response.data) { @@ -53,6 +52,15 @@ export const useDictionaryStore = create()((set, get) => ({ dictionaryData: dictionaryData || {}, isLoading: false }) + + set({ + bannerDict: { + bannerListImage: response.data.bannerListImage || '', + bannerDetailImage: response.data.bannerDetailImage || '', + bannerListIndex: (response.data.bannerListIndex ?? '').toString(), + } + }) + console.log('字典数据获取成功:', response.data) } else { throw new Error(response.message || '获取字典数据失败') @@ -67,26 +75,7 @@ export const useDictionaryStore = create()((set, get) => ({ } }, - // 获取 Banner 字典(启动时或手动调用) - fetchBannerDictionary: async () => { - try { - const keys = 'bannerListImage,bannerDetailImage,bannerListIndex'; - const response = await commonApi.getDictionaryManyKey(keys) - if (response.code === 0 && response.data) { - const data = response.data || {}; - set({ - bannerDict: { - bannerListImage: data.bannerListImage || '', - bannerDetailImage: data.bannerDetailImage || '', - bannerListIndex: (data.bannerListIndex ?? '').toString(), - } - }) - } - } catch (error) { - // 保持静默,避免影响启动流程 - console.error('获取 Banner 字典失败:', error) - } - }, + // 获取字典值 getDictionaryValue: (key: string, defaultValue?: any) => {