Skip to content

Conversation

@dethan3
Copy link
Member

@dethan3 dethan3 commented Nov 16, 2025

PR-39 PR-39 PR-39 Powered by Pull Request Badge

Checklist(清单):

  • Labels
  • Assignees
  • Reviewers

freeCodeChengDu 周末编程自习室 WorkShop 作品
2025/11/15

Reviewer changes

  1. [refactor] split Spark Line component into an independent module
  2. [optimize] simplify CSS modules & Finance page
  3. [optimize] generate Next.js types automatically
  4. [migrate] upgrade to Next.js 16, Koa Router 15, Marked 17, ECharts-JSX 0.6 & other latest Upstream packages

Summary by CodeRabbit

  • 新功能

    • 新增财务指数基金发现页面,支持按资产类别与风险等级筛选并展示筛选摘要
    • 新增基金卡片组件,显示最新价值、日涨跌、一年回报、最大回撤、更新时间、标签与详情链接,内置小型走势图与错误回退
    • 新增后端快照 API,包含缓存、历史数据拉取与确定性合成回退数据
    • 新增独立 SparkLine 图表组件与相关导出类型
  • 样式

    • 新增模块化样式,提供响应式网格、卡片与图表视觉规范
  • 空状态

    • 添加友好空结果提示与重置操作

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 16, 2025

Walkthrough

新增完整的指数基金发现功能:包含前端 FundCard 与 SparkLine 组件、MobX 的 IndexFundModel 存储、Next.js API 路由(带 60s 内存缓存与合成数据降级)、以及集成的金融着陆页与相关样式与类型声明。

Changes

内聚群组 / 文件(s) 变更摘要
前端 UI — 基金卡片
components/Finance/FundCard.tsx, components/Finance/Finance.module.less
新增 FundCard React + TypeScript 组件并导出 const FundCard: FC<IndexFundSnapshot>;渲染头部(名称、分类、风险、来源)、描述、指标(最新值、日变、年回报、最大回撤)、可选标签、更新时间与详情链接;使用 SparkLine 内联图表并依赖模块样式。样式文件新增卡片、指标、徽章、正负色等样式。
前端 UI — Sparkline
components/Finance/SparkLine.tsx, components/Finance/SparkLine.module.less
新增 SparkLine 组件(导出类 SparkLine 与接口 SparkLineProps),计算 polyline 与渐变 stops,渲染 SVG sparkline 或占位;新增对应 LESS 样式(尺寸、placeholder 样式)。
状态管理 (MobX)
models/Finance.ts
新增基于 ListModelIndexFundModel(baseURI=finance/index-funds, pageSize=8),新增接口 IndexFundFilter,实现 loadPage 以 category/riskLevel 构建查询并通过 ownClient 拉取,导出单例 indexFundStore
后端 API 路由
pages/api/finance/index-funds.ts
新增 Next.js API 路由(koa-router 封装):内置 PRESETS 基线基金元数据、历史序列拉取与归一化、失败时确定性合成数据生成 sparkline 与指标,计算 dailyChangePct/oneYearReturnPct/maxDrawdownPct,内存缓存(TTL=60s)、支持 category/riskLevel/limit 过滤,响应包含 metadata 并设置 Cache-Control。
页面集成与样式
pages/finance/index.tsx, pages/finance/index.module.less
新增金融着陆页 FinanceLandingPage(默认导出并由 MobX observer 包装):i18n 集成、可观察滤器状态、分段控件、英雄区、KPI 面板、ScrollList 结合 indexFundStore 渲染 FundCard 网格、加载/空状态处理;新增页面样式(hero、filter、列表、空状态、教育区)。
类型/翻译声明
models/Translation.ts
新增导出类型别名 I18nKey = keyof typeof zhCN,用于 i18n 键的强类型约束。

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Page as FinanceLandingPage
    participant Store as indexFundStore (MobX)
    participant API as /api/finance/index-funds
    participant Cache as In-Memory Cache (TTL=60s)
    participant Source as AkShare / Synthetic

    User->>Page: 打开页面或更改筛选
    Page->>Store: loadPage(category, riskLevel)
    Store->>API: GET /api/finance/index-funds?category=X&riskLevel=Y&limit=8
    API->>Cache: 检查缓存
    alt 缓存命中
        Cache-->>API: 返回缓存快照
    else 缓存未命中
        API->>Source: 请求历史序列 (AkShare)
        alt 拉取成功
            Source-->>API: 返回历史数据
        else 拉取失败
            API->>Source: 生成确定性合成数据 (seeded)
            Source-->>API: 返回合成序列
        end
        API->>Cache: 写入缓存(TTL=60s)
    end
    API-->>Store: 返回 IndexFundSnapshot[] 与 metadata
    Store-->>Page: observable 更新触发重新渲染
    Page->>Page: 渲染 FundCard 与 SparkLine SVG
    Page-->>User: 展示基金列表 / 加载 / 空状态
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

重点审查建议:

  • models/Finance.ts:确认 IndexFundModel.loadPage 的泛型、分页与 total 计算、错误路径处理与 MobX observable/action/computed 的正确使用。
  • pages/api/finance/index-funds.ts:校验缓存一致性(TTL)、安全解析 query(category/riskLevel/limit)、AkShare 响应形态分支、合成数据的确定性与边界条件、以及 Cache-Control header 设置与错误码处理。
  • components/Finance/FundCard.tsx / SparkLine.tsx:确保所有 UI 文本使用 t() 国际化、组件的 TypeScript 签名没有 any、SparkLine 计算(polyline/gradient)在依赖变化时正确重算且避免不必要的重渲染。
  • 性能与可访问性:检查 SVG 渲染、next/image(如使用)与首屏性能;确认 aria/label 与 i18n 用法。

Poem

基金卡片轻启航,📈
Sparkline 曲线画光芒,✨
MobX 观测悄无声,🔁
缓存六十稳又长,🕒
降级合成亦自芳。

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题'[add] Wealth Product selector page'与变更集内容不完全匹配。变更涉及完整的理财产品页面(包括API路由、FundCard组件、SparkLine可视化、MobX存储模型、页面布局等),但标题措辞过于笼统,未体现核心实现的多个关键部分。
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch finance

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@dosubot
Copy link

dosubot bot commented Nov 16, 2025

Related Documentation

Checked 10 published document(s) in 1 knowledge base(s). No updates required.

How did I do? Any feedback?  Join Discord

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 14

🧹 Nitpick comments (1)
pages/api/finance/index-funds.ts (1)

100-100: 模块级缓存在 API Routes 中可接受,但需要注意 Serverless 限制

Next.js API Routes 在 serverless 环境中每个请求可能使用不同的实例,模块级缓存可能不一致。如果部署到 Vercel 等 serverless 平台,建议迁移到 Redis 或 Next.js 内置的 unstable_cache。

考虑使用 Next.js 15 的 caching API:

import { unstable_cache } from 'next/cache';

const getCachedSnapshots = unstable_cache(
  async () => loadSnapshots(),
  ['index-fund-snapshots'],
  { revalidate: 60, tags: ['finance'] }
);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 89da576 and 4162281.

⛔ Files ignored due to path filters (7)
  • constants/finance.ts is excluded by none and included by none
  • finance_PRD.md is excluded by !**/*.md and included by none
  • lib/akshare.ts is excluded by none and included by none
  • lib/finance.ts is excluded by none and included by none
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml, !pnpm-lock.yaml and included by none
  • styles/Finance.module.scss is excluded by none and included by none
  • types/finance.ts is excluded by none and included by none
📒 Files selected for processing (4)
  • components/Finance/FundCard.tsx (1 hunks)
  • models/Finance.ts (1 hunks)
  • pages/api/finance/index-funds.ts (1 hunks)
  • pages/finance/index.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
{pages,components}/**/*.tsx

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

{pages,components}/**/*.tsx: ALWAYS use React Bootstrap components instead of custom HTML elements in UI code
Use semantic HTML structure (article, header, section); use

    for countable items,
      for navigation; apply list-unstyled on first-level lists
      All user-facing text MUST use the i18n t() function (no hardcoded strings)
      Use React Bootstrap 2.10 components consistently for responsive design

Files:

  • pages/finance/index.tsx
  • components/Finance/FundCard.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use optional chaining and modern ECMAScript features
Let TypeScript infer types when possible to avoid verbose annotations
Import from established sources (e.g., ContentModel from mobx-github, utilities from web-utility) rather than reimplementing
Use minimal exports and avoid unnecessary custom implementations

Files:

  • pages/finance/index.tsx
  • models/Finance.ts
  • components/Finance/FundCard.tsx
  • pages/api/finance/index-funds.ts
pages/**/*.tsx

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

For static generation, allow errors to bubble naturally (do not swallow errors)

Files:

  • pages/finance/index.tsx
models/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

models/**/*.ts: Import './Base' in model files to ensure proper GitHub client configuration
Use ContentModel with the configured client from mobx-github for content access
Use treeFrom utility from web-utility for hierarchical data structures

Files:

  • models/Finance.ts
{models,pages/api}/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Import and use the configured githubClient from models/Base.ts; do not create new GitHub API instances

Files:

  • models/Finance.ts
  • pages/api/finance/index-funds.ts
{models,pages/api}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Decode Base64 GitHub content using atob(item.content) when processing responses

Files:

  • models/Finance.ts
  • pages/api/finance/index-funds.ts
🧠 Learnings (3)
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to {pages,components}/**/*.tsx : All user-facing text MUST use the i18n t() function (no hardcoded strings)

Applied to files:

  • pages/finance/index.tsx
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to models/**/*.ts : Import './Base' in model files to ensure proper GitHub client configuration

Applied to files:

  • models/Finance.ts
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to models/**/*.ts : Use ContentModel with the configured client from mobx-github for content access

Applied to files:

  • models/Finance.ts
🧬 Code graph analysis (2)
pages/finance/index.tsx (4)
models/Translation.ts (2)
  • i18n (36-36)
  • I18nContext (44-44)
models/Finance.ts (2)
  • IndexFundFilter (6-9)
  • indexFundStore (48-48)
components/Layout/PageHead.tsx (1)
  • PageHead (11-23)
components/Finance/FundCard.tsx (1)
  • FundCard (76-171)
models/Finance.ts (1)
models/Base.ts (1)
  • ownClient (19-22)
🔇 Additional comments (10)
components/Finance/FundCard.tsx (1)

21-43: Sparkline 组件性能优化得当

useMemo 的使用避免了不必要的计算,polyline 和 gradient 的计算逻辑清晰。边界处理(空数组、除零保护)处理得当。

models/Finance.ts (3)

1-9: 模型结构符合规范

正确导入 ownClient from './Base',符合编码规范要求。类型定义清晰,IndexFundFilter 接口设计合理,支持可选的 category 和 riskLevel 过滤。

根据 learnings 要求:在 model 文件中导入 './Base' 以确保正确的 GitHub 客户端配置。


16-46: ListModel 使用正确,loadPage 实现规范

IndexFundModel 正确继承 ListModel,使用 ownClient 进行 API 调用。loadPage 方法实现规范:

  • 正确构建 URLSearchParams 查询参数
  • 处理可选过滤器(category、riskLevel)
  • 返回符合 ListModel 要求的 { pageData, totalCount } 结构
  • 使用可选链和空值合并运算符处理边界情况

48-48: 单例导出符合最佳实践

导出 indexFundStore 单例实例,便于跨组件共享状态,符合 MobX 使用模式。

pages/api/finance/index-funds.ts (4)

16-19: 常量定义清晰,缓存策略合理

60 秒 TTL 平衡了数据新鲜度与 API 调用频率。HISTORY_SPARKLINE_POINTS 和 FALLBACK_HISTORY_POINTS 的区分使得展示数据与降级数据有不同的粒度。


213-233: 降级策略设计优秀

错误处理健壮:在无法获取真实数据时,使用确定性的合成数据(seededRandom)而非随机数据,确保同一 symbol 每次降级返回相同的结果。这对用户体验和调试都很友好。同时记录 console.warn 便于监控。


273-300: API handler 实现规范

  • 正确验证 HTTP 方法(仅允许 GET)
  • 设置适当的 Cache-Control 头(s-maxage=60, stale-while-revalidate=300)
  • 返回结构化的响应(data + meta)
  • 统一的错误处理和状态码

160-168: seededRandom 实现的确定性保证数据一致性

使用线性同余生成器(LCG)基于 symbol 字符串生成伪随机数,确保相同 symbol 每次调用生成相同的序列。这对降级场景非常重要。

pages/finance/index.tsx (2)

29-46: MobX observer 使用正确

组件正确使用 observer 包装,能够响应 indexFundStore 的状态变化。本地状态管理(category、riskLevel)使用 useState 合理,filter 对象的构建方式符合 MobX 最佳实践。


192-215: ScrollList 集成正确

正确传递 store、translator、filter 和 renderList 属性。renderList 回调中的响应式布局(Row/Col)使用得当,空状态处理完善。

@dethan3 dethan3 requested a review from TechQuery November 16, 2025 14:56
@dethan3 dethan3 self-assigned this Nov 16, 2025
@TechQuery TechQuery added the feature New feature or request label Nov 16, 2025
@github-project-automation github-project-automation bot moved this from Ready to In progress in 官网项目群 Nov 26, 2025
- Replace hardcoded Chinese copy in /pages/finance and FundCard with i18n t() calls
- Refactor finance constants to export i18n label keys instead of raw strings
- Add finance-related translation entries for zh-CN, en-US, and zh-TW
- Move Finance styles from global SCSS to co-located Finance.module.less
- Tweak AkShare/finance data utilities and API handler to align with new flow
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
models/Finance.ts (1)

24-34: loadPage 方法应遵循既有评审建议进行重构。

当前实现存在以下问题:

  1. 方法签名与 ListModel 的分页机制集成不够清晰
  2. 查询构建逻辑应提取,保持方法职责单一
  3. 既往评审已提供更清晰的实现方案

请参考既往评审建议,应用以下重构:

+  @observable
+  accessor pageSize = 8;

-  async loadPage(page = this.pageIndex, limit = this.pageSize, filter: IndexFundFilter = {}) {
-    const query = buildURLData({ ...filter, limit }).toString();
-    const path = query ? `${this.baseURI}?${query}` : this.baseURI;
-
-    const { body } = await this.client.get<IndexFundAPIResponse>(path);
-
-    const pageData = body?.data || [];
-    const totalCount = body?.meta?.total ?? pageData.length;
-
-    return { pageData, totalCount };
-  }
+  async loadPage(page: number, limit: number, filter: IndexFundFilter) {
+    const { body } = await this.client.get<IndexFundAPIResponse>(
+      `${this.baseURI}?${buildURLData({ ...filter, limit })}`
+    );
+
+    const pageData = body?.data || [];
+    const totalCount = body?.meta?.total ?? pageData.length;
+
+    return { pageData, totalCount };
+  }

基于既往评审建议。

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4162281 and 3a1f964.

⛔ Files ignored due to path filters (6)
  • constants/finance.ts is excluded by none and included by none
  • lib/akshare.ts is excluded by none and included by none
  • lib/finance.ts is excluded by none and included by none
  • translation/en-US.ts is excluded by none and included by none
  • translation/zh-CN.ts is excluded by none and included by none
  • translation/zh-TW.ts is excluded by none and included by none
📒 Files selected for processing (5)
  • components/Finance/Finance.module.less (1 hunks)
  • components/Finance/FundCard.tsx (1 hunks)
  • models/Finance.ts (1 hunks)
  • pages/api/finance/index-funds.ts (1 hunks)
  • pages/finance/index.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • components/Finance/Finance.module.less
🚧 Files skipped from review as they are similar to previous changes (1)
  • pages/finance/index.tsx
🧰 Additional context used
📓 Path-based instructions (5)
models/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

models/**/*.ts: Import './Base' in model files to ensure proper GitHub client configuration
Use ContentModel with the configured client from mobx-github for content access
Use treeFrom utility from web-utility for hierarchical data structures

Files:

  • models/Finance.ts
{models,pages/api}/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Import and use the configured githubClient from models/Base.ts; do not create new GitHub API instances

Files:

  • models/Finance.ts
  • pages/api/finance/index-funds.ts
{models,pages/api}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Decode Base64 GitHub content using atob(item.content) when processing responses

Files:

  • models/Finance.ts
  • pages/api/finance/index-funds.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use optional chaining and modern ECMAScript features
Let TypeScript infer types when possible to avoid verbose annotations
Import from established sources (e.g., ContentModel from mobx-github, utilities from web-utility) rather than reimplementing
Use minimal exports and avoid unnecessary custom implementations

Files:

  • models/Finance.ts
  • pages/api/finance/index-funds.ts
  • components/Finance/FundCard.tsx
{pages,components}/**/*.tsx

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

{pages,components}/**/*.tsx: ALWAYS use React Bootstrap components instead of custom HTML elements in UI code
Use semantic HTML structure (article, header, section); use

    for countable items,
      for navigation; apply list-unstyled on first-level lists
      All user-facing text MUST use the i18n t() function (no hardcoded strings)
      Use React Bootstrap 2.10 components consistently for responsive design

Files:

  • components/Finance/FundCard.tsx
🧠 Learnings (7)
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to models/**/*.ts : Use ContentModel with the configured client from mobx-github for content access

Applied to files:

  • models/Finance.ts
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to {pages,components}/**/*.tsx : All user-facing text MUST use the i18n t() function (no hardcoded strings)

Applied to files:

  • components/Finance/FundCard.tsx
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to {pages,components}/**/*.tsx : Use React Bootstrap 2.10 components consistently for responsive design

Applied to files:

  • components/Finance/FundCard.tsx
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to {pages,components}/**/*.tsx : ALWAYS use React Bootstrap components instead of custom HTML elements in UI code

Applied to files:

  • components/Finance/FundCard.tsx
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to translation/{zh-CN,en-US,zh-TW}.ts : Prefer generic translation keys unless specifically scoped (e.g., t('knowledge_base') over t('policy_documents'))

Applied to files:

  • components/Finance/FundCard.tsx
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to translation/{zh-CN,en-US,zh-TW}.ts : Remove unused translation keys when replacing with generic ones

Applied to files:

  • components/Finance/FundCard.tsx
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to {pages,components}/**/*.tsx : Use semantic HTML structure (article, header, section); use <ol> for countable items, <ul> for navigation; apply list-unstyled on first-level lists

Applied to files:

  • components/Finance/FundCard.tsx
🧬 Code graph analysis (3)
models/Finance.ts (1)
models/Base.ts (1)
  • ownClient (19-22)
pages/api/finance/index-funds.ts (1)
pages/api/core.ts (1)
  • safeAPI (16-45)
components/Finance/FundCard.tsx (1)
models/Translation.ts (1)
  • I18nContext (44-44)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build-and-Deploy
🔇 Additional comments (10)
models/Finance.ts (1)

18-22: 类定义结构正确,符合 MobX 规范。

IndexFundModel 正确继承 ListModel,使用 ownClient 符合编码规范(避免重复创建 GitHub API 实例),@observable accessor 用法正确。

components/Finance/FundCard.tsx (4)

22-74: Sparkline 组件实现优秀。

  • 正确使用 useMemo 优化 polyline 计算,避免不必要的重渲染
  • aria-label 已正确国际化
  • 梯度渐变和 SVG 路径生成逻辑清晰

76-132: 组件头部和描述区域实现正确。

  • 正确解构 IndexFundSnapshot props,TypeScript 类型安全
  • React Bootstrap Card 和 Badge 组件使用规范
  • 所有用户可见文本已通过 t() 国际化

134-146: 指标行使用语义化 HTML 标记,符合规范。

  • 使用 dl/dt/dd 描述列表结构,语义清晰
  • 所有指标标签已正确国际化(t() 函数)
  • formatNumber 和 formatPercent 辅助函数应用得当
  • valueTone 动态样式类根据正负值着色,用户体验友好

注意:formatNumber 的 locale 硬编码问题已在单独评论中标记。


162-164: 时间元素使用语义化标记,符合 HTML5 规范。

使用 <time> 元素配合 dateTime 属性,提升可访问性和 SEO,更新时间文本已正确国际化。

pages/api/finance/index-funds.ts (5)

19-22: 常量定义清晰合理。

缓存 TTL 为 60 秒,适合金融数据的实时性要求;历史数据点数量配置明确。


116-136: AkShare 数据处理健壮且规范。

  • unwrapAkShareRecords 正确处理多种响应格式(直接数组、data 字段、result 字段)
  • normalizeHistory 支持双语字段名(date/日期、close/收盘),适配 AkShare API 特性
  • TypeScript 类型守卫确保类型安全,日期排序逻辑正确

157-189: 合成数据回退机制设计优秀。

  • seededRandom 基于 symbol 生成确定性随机序列,确保同一基金的回退数据可复现
  • 合成走势加入 ±2% 噪声,模拟真实波动
  • 提供了弹性和可用性保障,即使外部数据源不可用,用户仍能看到演示数据

这是防御性编程的良好实践。


211-242: 快照构建和缓存逻辑正确。

  • buildSnapshot 使用 try/catch 捕获异常,失败时降级到合成数据
  • 日志记录(console.warn)便于监控和调试
  • 缓存机制基于时间戳和 TTL 判断,避免频繁请求外部 API
  • Promise.all 并行加载所有基金数据,性能优化得当

275-301: API 路由实现专业且完整。

  • safeAPI 中间件统一处理错误,避免服务器崩溃
  • 响应包含 meta 元数据(total、returned、cached、source),便于前端调试和监控
  • Cache-Control 标头设置 's-maxage=60, stale-while-revalidate=300',利用 CDN 缓存和过期重新验证策略,优化性能
  • 过滤逻辑处理查询参数数组格式,健壮性强

基于 learnings:使用 safeAPI 包装器是既定模式。

Comment on lines +154 to +160
<ul className="list-unstyled m-0 d-flex flex-wrap gap-2">
{tags?.map(tag => (
<Badge key={tag} as="li" bg="light" text="dark" className={styles.tagBadge}>
{tag}
</Badge>
))}
</ul>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

标签(tags)未国际化处理。

当前 tags 数组中的字符串(如 '宽基'、'蓝筹')直接渲染,在非中文环境下会显示中文文本,违反国际化规范。

建议方案:

方案 1(推荐):在 constants/finance.ts 中定义标签映射,类似 INDEX_CATEGORY_LABEL_KEYS:

// constants/finance.ts
export const INDEX_TAG_LABEL_KEYS: Record<string, string> = {
  '宽基': 'fund_tag_broad_base',
  '蓝筹': 'fund_tag_blue_chip',
  '成长': 'fund_tag_growth',
  // ... 其他标签
};

然后在组件中映射:

         <ul className="list-unstyled m-0 d-flex flex-wrap gap-2">
           {tags?.map(tag => (
             <Badge key={tag} as="li" bg="light" text="dark" className={styles.tagBadge}>
-              {tag}
+              {t(INDEX_TAG_LABEL_KEYS[tag] || tag)}
             </Badge>
           ))}
         </ul>

方案 2:API 返回标签的 key 而非中文字符串,组件通过 key 查找翻译。

基于 learnings:所有用户可见文本必须使用 t() 函数。

🤖 Prompt for AI Agents
In components/Finance/FundCard.tsx around lines 154 to 160, the tags array is
rendered as raw Chinese strings which bypasses i18n; replace direct rendering
with translated labels by mapping tag values to translation keys (add an
INDEX_TAG_LABEL_KEYS or INDEX_TAG_KEY_MAP in constants/finance.ts mapping
Chinese tag strings to i18n keys), then in the component map each tag to
t(INDEX_TAG_LABEL_KEYS[tag] || tag) when rendering the Badge (use the original
tag as a safe fallback if no mapping exists); alternatively, if the API can be
changed, accept tag keys and call t(key) directly—ensure every user-visible tag
uses t() before render.

[optimize] simplify CSS modules & Finance page
[migrate] upgrade to Next.js 16, Koa Router 15, Marked 17, ECharts-JSX 0.6 & other latest Upstream packages
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (4)
components/Finance/FundCard.tsx (3)

10-17: 数值/百分比格式化可以进一步收紧类型并统一 locale 处理

目前 formatNumber 已支持传入 locale 并在调用处使用 currentLanguage,比之前硬编码 'zh-CN' 更合理。不过可以进一步改进两点:

  1. 将第二个参数类型收紧为 LanguageCode,例如从 models/Translation 中引入后写成:
    const formatNumber = (value?: number | null, locale: LanguageCode = 'zh-CN') => ...;
    这样可以防止误传无效 locale 字符串。
  2. formatPercent 仍然是固定 toFixed(2) 拼接 "%",如果希望百分比的小数点和分组符也随 locale 变化,可以比照 formatNumber 接收 locale,内部通过 toLocaleString 处理,再拼接 %

这两点都属于增强 i18n 体验的优化,可按业务需要择机调整。


67-70: 数据源文本的换行建议用块级结构代替 <br />

现在通过 <small> 内嵌一个 <br /> 强制换行,语义上略显生硬,也不利于样式复用。建议改为两个块级(或 d-block)元素,例如:

-          <small className="text-muted text-end">
-            {t('data_source')} <br />
-            {source.historyEndpoint}
-          </small>
+          <small className="text-muted text-end d-flex flex-column">
+            <span>{t('data_source')}</span>
+            <span>{source.historyEndpoint}</span>
+          </small>

既保持当前视觉,又更符合结构化 HTML 的最佳实践。


91-97: tags 仍然是硬编码中文字符串,需通过 i18n 映射

tags 数组目前直接渲染 {tag},如果后端传入的是中文标签(如“宽基”、“蓝筹”),在非中文语言下就会违背“所有面向用户的文本必须通过 t()”的规范,也与之前的 review 建议不符。建议:

  • constants/finance.ts 中新增映射,例如:

    export const INDEX_TAG_LABEL_KEYS: Record<string, I18nKey> = {
      宽基: 'fund_tag_broad_base',
      蓝筹: 'fund_tag_blue_chip',
      // ...
    };
  • 组件中渲染时做 key 映射并通过 t() 输出:

    -          {tags?.map(tag => (
    -            <Badge key={tag} as="li" bg="light" text="dark" className={styles.tagBadge}>
    -              {tag}
    -            </Badge>
    -          ))}
    +          {tags?.map(tag => (
    +            <Badge key={tag} as="li" bg="light" text="dark" className={styles.tagBadge}>
    +              {t(INDEX_TAG_LABEL_KEYS[tag] || tag)}
    +            </Badge>
    +          ))}

或让 API 直接返回标签 key,再在前端 t(key) 渲染。

pages/finance/index.tsx (1)

60-72: filterSummary 中的分隔符建议也通过 i18n 控制

filterSummary 里目前是:

return `${categoryText} · ${riskText}`;

虽然只是一个“·”分隔符,但它依然属于用户可见文本,不同语言对分隔符和前后空格的习惯可能不同。建议将整个 summary 或至少分隔符抽成翻译 key,例如:

return t('finance_filter_summary', { category: categoryText, risk: riskText });
// 或者
return `${categoryText}${t('finance_filter_separator')}${riskText}`;

这样在不同语言里可以自由调整格式。

🧹 Nitpick comments (3)
components/Finance/SparkLine.tsx (1)

14-88: SparkLine 计算与 i18n 使用整体正确,仅有微小优化空间

chartData 对空数据和等值数据的处理都很稳健,SVG aria-label 和无数据占位都通过 t() 国际化,符合现有规范。唯一可以考虑的小优化是:gradientOffsets 是完全常量,可以提到文件顶层常量(如 const GRADIENT_STOPS = [0, 50, 100] as const;),chartData 直接返回该常量,避免每次 @computed 访问时新建数组——当前性能影响很小,可视情况再做。

components/Finance/FundCard.tsx (1)

99-105: 内部路由跳转建议改用 React Bootstrap / Next Link,避免完整刷新

目前底部“查看详情”使用原生 <a href={/finance/${symbol}}>,在 Next.js 环境下会触发整页刷新,不利于性能和体验,也与“统一使用 React Bootstrap 组件”的约定不太一致。可以考虑:

-import { Badge, Card } from 'react-bootstrap';
+import { Badge, Card, Button } from 'react-bootstrap';
...
-        <a href={`/finance/${symbol}`} className="text-primary fw-semibold">
-          {t('view_details')}
-        </a>
+        <Button
+          variant="link"
+          href={`/finance/${symbol}`}
+          className="p-0 text-primary fw-semibold align-self-start"
+        >
+          {t('view_details')}
+        </Button>

或使用 next/link 包裹,保持客户端路由行为。

pages/finance/index.tsx (1)

76-117: 分段筛选按钮可考虑改用 React Bootstrap Button 以统一组件风格

renderCategory / renderRisk 目前使用原生 <button> 配合 styles.button/styles.active 控制样式,在功能上完全可用。但从整体代码风格和规范里“优先使用 React Bootstrap 组件”的角度,可以考虑改为:

-import { Badge, Button, Col, Container, Row } from 'react-bootstrap';
+import { Badge, Button, Col, Container, Row } from 'react-bootstrap';
...
-    return (
-      <button
-        key={labelKey}
-        type="button"
-        className={`${styles.button} ${active ? styles.active : ''}`}
-        onClick={...}
-      >
-        {t(labelKey)}
-      </button>
-    );
+    return (
+      <Button
+        key={labelKey}
+        type="button"
+        className={`${styles.button} ${active ? styles.active : ''}`}
+        onClick={...}
+      >
+        {t(labelKey)}
+      </Button>
+    );

同理可应用于 renderRisk。保留现有样式 class 的同时,交互语义上完全由 React Bootstrap 接管,更利于后续统一维护。

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a1f964 and 4d89463.

⛔ Files ignored due to path filters (6)
  • README.md is excluded by !**/*.md and included by none
  • constants/finance.ts is excluded by none and included by none
  • eslint.config.ts is excluded by none and included by none
  • lib/akshare.ts is excluded by none and included by none
  • package.json is excluded by none and included by none
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml, !pnpm-lock.yaml and included by none
📒 Files selected for processing (9)
  • components/Finance/Finance.module.less (1 hunks)
  • components/Finance/FundCard.tsx (1 hunks)
  • components/Finance/SparkLine.module.less (1 hunks)
  • components/Finance/SparkLine.tsx (1 hunks)
  • models/Finance.ts (1 hunks)
  • models/Translation.ts (1 hunks)
  • pages/api/finance/index-funds.ts (1 hunks)
  • pages/finance/index.module.less (1 hunks)
  • pages/finance/index.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • pages/api/finance/index-funds.ts
🧰 Additional context used
📓 Path-based instructions (6)
models/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

models/**/*.ts: Import './Base' in model files to ensure proper GitHub client configuration
Use ContentModel with the configured client from mobx-github for content access
Use treeFrom utility from web-utility for hierarchical data structures

Files:

  • models/Finance.ts
  • models/Translation.ts
{models,pages/api}/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Import and use the configured githubClient from models/Base.ts; do not create new GitHub API instances

Files:

  • models/Finance.ts
  • models/Translation.ts
{models,pages/api}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Decode Base64 GitHub content using atob(item.content) when processing responses

Files:

  • models/Finance.ts
  • models/Translation.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use optional chaining and modern ECMAScript features
Let TypeScript infer types when possible to avoid verbose annotations
Import from established sources (e.g., ContentModel from mobx-github, utilities from web-utility) rather than reimplementing
Use minimal exports and avoid unnecessary custom implementations

Files:

  • models/Finance.ts
  • pages/finance/index.tsx
  • models/Translation.ts
  • components/Finance/SparkLine.tsx
  • components/Finance/FundCard.tsx
{pages,components}/**/*.tsx

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

{pages,components}/**/*.tsx: ALWAYS use React Bootstrap components instead of custom HTML elements in UI code
Use semantic HTML structure (article, header, section); use

    for countable items,
      for navigation; apply list-unstyled on first-level lists
      All user-facing text MUST use the i18n t() function (no hardcoded strings)
      Use React Bootstrap 2.10 components consistently for responsive design

Files:

  • pages/finance/index.tsx
  • components/Finance/SparkLine.tsx
  • components/Finance/FundCard.tsx
pages/**/*.tsx

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

For static generation, allow errors to bubble naturally (do not swallow errors)

Files:

  • pages/finance/index.tsx
🧠 Learnings (9)
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to models/**/*.ts : Import './Base' in model files to ensure proper GitHub client configuration

Applied to files:

  • models/Finance.ts
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to models/**/*.ts : Use ContentModel with the configured client from mobx-github for content access

Applied to files:

  • models/Finance.ts
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to {pages,components}/**/*.tsx : All user-facing text MUST use the i18n t() function (no hardcoded strings)

Applied to files:

  • pages/finance/index.tsx
  • components/Finance/FundCard.tsx
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to translation/{zh-CN,en-US,zh-TW}.ts : Remove unused translation keys when replacing with generic ones

Applied to files:

  • pages/finance/index.tsx
  • models/Translation.ts
  • components/Finance/FundCard.tsx
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to translation/{zh-CN,en-US,zh-TW}.ts : Prefer generic translation keys unless specifically scoped (e.g., t('knowledge_base') over t('policy_documents'))

Applied to files:

  • pages/finance/index.tsx
  • models/Translation.ts
  • components/Finance/FundCard.tsx
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to translation/{zh-CN,en-US,zh-TW}.ts : Add translation keys to ALL language files (zh-CN.ts, en-US.ts, zh-TW.ts) when introducing text

Applied to files:

  • pages/finance/index.tsx
  • models/Translation.ts
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to {pages,components}/**/*.tsx : Use semantic HTML structure (article, header, section); use <ol> for countable items, <ul> for navigation; apply list-unstyled on first-level lists

Applied to files:

  • pages/finance/index.tsx
  • components/Finance/FundCard.tsx
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to {pages,components}/**/*.tsx : Use React Bootstrap 2.10 components consistently for responsive design

Applied to files:

  • components/Finance/FundCard.tsx
📚 Learning: 2025-09-11T00:30:03.492Z
Learnt from: CR
Repo: Open-Source-Bazaar/Open-Source-Bazaar.github.io PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-11T00:30:03.492Z
Learning: Applies to {pages,components}/**/*.tsx : ALWAYS use React Bootstrap components instead of custom HTML elements in UI code

Applied to files:

  • components/Finance/FundCard.tsx
🧬 Code graph analysis (4)
models/Finance.ts (1)
models/Base.ts (1)
  • ownClient (19-22)
pages/finance/index.tsx (3)
models/Translation.ts (3)
  • I18nKey (21-21)
  • i18n (38-38)
  • I18nContext (46-46)
models/Finance.ts (2)
  • IndexFundFilter (8-11)
  • indexFundStore (35-35)
components/Layout/PageHead.tsx (1)
  • PageHead (11-23)
components/Finance/SparkLine.tsx (2)
pages/finance/index.tsx (1)
  • observer (53-275)
models/Translation.ts (2)
  • i18n (38-38)
  • I18nContext (46-46)
components/Finance/FundCard.tsx (1)
models/Translation.ts (1)
  • I18nContext (46-46)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build-and-Deploy
🔇 Additional comments (5)
models/Translation.ts (1)

21-21: I18nKey 类型设计合理,但注意保持多语言 key 一致

keyof typeof zhCN 约束 i18n key 很好,可以在编译期防止拼写错误。建议同步确认:本次新增的 finance_* / index_* 等文案 key 已在 zh-CN.tsen-US.tszh-TW.ts 三个翻译文件中全部补齐,避免其它语言运行时才暴露缺失。

Based on learnings, translation/{zh-CN,en-US,zh-TW}.ts 需要保持 key 集合一致。

components/Finance/SparkLine.module.less (1)

1-17: SparkLine 样式与组件结构匹配良好

容器高度、SVG 尺寸和占位样式都与组件实现一一对应,当前实现简单直接,没有明显可见问题。

components/Finance/Finance.module.less (1)

1-41: FundCard 相关样式命名清晰,状态色选择合理

卡片、指标和值、标签和正负色样式与 FundCard 组件的语义结构相匹配,色值也与 Bootstrap 成功/危险色保持一致,当前实现可直接接受。

pages/finance/index.module.less (1)

1-100: Finance 页面样式组织良好,与 TSX 结构一一对应

各区域(hero、筛选面板、列表卡片、空状态、教育区)的阴影、圆角和布局 class 与 pages/finance/index.tsx 中的使用保持一致,分段选择器 .segmentedControl .button/.active 也能很好支持自定义筛选按钮,目前没有发现样式层面的明显问题。

pages/finance/index.tsx (1)

123-271: FinanceLandingPage 结构清晰,MobX 与 i18n 集成规范

主渲染流程将页面拆成 hero、筛选面板、基金列表和教育区域四大块:

  • 使用 Container/Row/Col/Badge/Button 等 React Bootstrap 组件构建布局,符合项目既有风格;
  • 所有标题、文案、按钮和空状态都通过 t() 调用 i18n key,未发现新的硬编码文本;
  • 筛选状态通过 @observable accessor filter 管理,并在 ScrollListfilter 属性中直接透传,结合 indexFundStore 的分页模型,整体数据流比较清晰。

在 models 中修正分页参数后,这个页面可以比较平滑地支持更多数据和滚动加载。

Comment on lines +24 to +32
async loadPage(page = this.pageIndex, limit = this.pageSize, filter: IndexFundFilter = {}) {
const { body } = await this.client.get<IndexFundAPIResponse>(
`${this.baseURI}?${buildURLData({ ...filter, limit })}`,
);
const pageData = body?.data || [];
const totalCount = body?.meta?.total ?? pageData.length;

return { pageData, totalCount };
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name "Finance.ts" -type f

Repository: Open-Source-Bazaar/Open-Source-Bazaar.github.io

Length of output: 110


🏁 Script executed:

find . -name "index-funds.ts" -type f | head -20

Repository: Open-Source-Bazaar/Open-Source-Bazaar.github.io

Length of output: 125


🏁 Script executed:

find . -name "ListModel.ts" -o -name "Base.ts" | grep -E "models/(ListModel|Base)"

Repository: Open-Source-Bazaar/Open-Source-Bazaar.github.io

Length of output: 107


🏁 Script executed:

cat -n ./models/Finance.ts

Repository: Open-Source-Bazaar/Open-Source-Bazaar.github.io

Length of output: 1385


🏁 Script executed:

cat -n ./pages/api/finance/index-funds.ts

Repository: Open-Source-Bazaar/Open-Source-Bazaar.github.io

Length of output: 10131


🏁 Script executed:

cat -n ./models/Base.ts

Repository: Open-Source-Bazaar/Open-Source-Bazaar.github.io

Length of output: 2665


🏁 Script executed:

rg "ListModel|loadPage" --type ts -A 3 -B 1 | head -100

Repository: Open-Source-Bazaar/Open-Source-Bazaar.github.io

Length of output: 2773


🏁 Script executed:

rg "IndexFundModel|indexFundStore" --type ts -A 2 -B 1

Repository: Open-Source-Bazaar/Open-Source-Bazaar.github.io

Length of output: 1499


🏁 Script executed:

sed -n '1,80p' ./models/Repository.ts

Repository: Open-Source-Bazaar/Open-Source-Bazaar.github.io

Length of output: 1819


🏁 Script executed:

rg "ScrollList|pagination|page|offset" pages/finance/index.tsx -B 2 -A 2

Repository: Open-Source-Bazaar/Open-Source-Bazaar.github.io

Length of output: 726


loadPage() receives page parameter but doesn't pass it to the API request

The method signature accepts page but the URL construction omits it:

`${this.baseURI}?${buildURLData({ ...filter, limit })}`

This should include the page parameter like the RepositorySearchModel does:

-      `${this.baseURI}?${buildURLData({ ...filter, limit })}`,
+      `${this.baseURI}?${buildURLData({ ...filter, page, limit })}`,

The ScrollList component expects pagination support. Without passing page, pagination will not function correctly when users scroll and attempt to load additional pages.

🤖 Prompt for AI Agents
In models/Finance.ts around lines 24 to 32, loadPage accepts a page parameter
but the constructed request URL omits it, breaking pagination; update the URL
construction to include the page value in the query (e.g., add page to the
object passed to buildURLData alongside filter and limit) so the API receives
the desired page index and ScrollList pagination works correctly.

@TechQuery TechQuery added the enhancement Some improvements label Dec 6, 2025
@github-project-automation github-project-automation bot moved this from In progress to In review in 官网项目群 Dec 6, 2025
@TechQuery TechQuery changed the title feat: 添加理财产品筛选页面 [add] Wealth Product selector page Dec 6, 2025
@TechQuery TechQuery merged commit 1ccc69c into main Dec 6, 2025
4 checks passed
@TechQuery TechQuery deleted the finance branch December 6, 2025 21:04
@github-project-automation github-project-automation bot moved this from In review to Done in 官网项目群 Dec 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Some improvements feature New feature or request

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants