feat: add invite commission feature with configurable ratio - #3030
feat: add invite commission feature with configurable ratio#3030nanashiwang wants to merge 5287 commits into
Conversation
feat(gemini): map OpenAI stop to Gemini stopSequences
fix: remove disable_parallel_tool_use if tool_choice=none
…t-price fix: /v1/responses/compact default billing
* feat: 引入通用 HTTP BodyStorage/DiskCache 缓存配置与管理 - 新增 common/body_storage.go 提供 HTTP 请求体存储抽象和文件缓存能力 - 增加 common/disk_cache_config.go 支持全局磁盘缓存配置 - main.go 挂载缓存初始化流程 - 新增和补充 controller/performance.go (及 unix/windows) 用于缓存性能监控接口 - middleware/body_cleanup.go 自动清理缓存文件 - router 挂载相关接口 - 前端 settings 页面新增性能监控设置 PerformanceSetting - 优化缓存开关状态和模块热插拔能力 - 其他相关文件同步适配缓存扩展 * fix: 修复 BodyStorage 并发安全和错误处理问题 - 修复 diskStorage.Close() 竞态条件,先获取锁再执行 CAS - 为 memoryStorage 添加互斥锁和 closed 状态检查 - 修复 CreateBodyStorageFromReader 在磁盘存储失败时的回退逻辑 - 添加缓存命中统计调用 (IncrementDiskCacheHits/IncrementMemoryCacheHits) - 修复 gin.go 中 Seek 错误被忽略的问题 - 在 api-router 添加 BodyStorageCleanup 中间件 - 修复前端 formatBytes 对异常值的处理 Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…uantumNous#2793) Explicitly cast Blocks, Bavail, and Bfree to uint64 for cross-platform compatibility, as these fields are int64 on FreeBSD but uint64 on Linux.
feat: Support customizing the success and cancel url of Stripe.
…65bf72572ff8684dd7ef068e576 feat: doubao add first and last image to video
…d7331d0987d96dc78bae181e331 feat: task pre consume modelPrice default use setting value
…3b7b97dbdbd98ade9b372bd6f63 feat: CodeViewer click link and auto wrap
…ling feat(gemini): support cached token billing
fix(ui): use distinct color palette for group tags
* fix: channel affinity log styles * fix: Issue with incorrect data storage when switching key sources * feat: support not retrying after a single rule configuration fails * fix: render channel affinity tooltip as multiline content * feat: channel affinity cache hit * fix: prevent ChannelAffinityUsageCacheModal infinite loading and hide data before fetch * chore: format backend with gofmt and frontend with prettier/eslint autofix
…st-override-take-effect fix: make channel Host override take effect
feat: /v1/responses qwen3 max && perplexity
…heck fix: violation fee check
…-encoding-passthrough fix: skip Accept-Encoding during header passthrough (QuantumNous#2214)
…detail feat: move user bindings to dedicated management modal
- Introduced a new test file for StreamScannerHandler, covering various scenarios including nil inputs, empty bodies, chunk processing, order preservation, and handler failures. - Enhanced error handling and data processing logic in StreamScannerHandler to improve robustness and performance.
feat(web): add custom-model create hint and i18n translations
…uting - Introduced RouteTag middleware to set route tags for different API endpoints. - Updated logger to include route tags in log output. - Applied RouteTag middleware across various routers including API, dashboard, relay, video, and web routers for consistent logging.
- Introduced InviteCommissionEnabled and InviteCommissionRatio constants. - Updated option handling to validate and store invite commission settings. - Enhanced top-up process to settle invite commissions based on the new settings. - Updated frontend components to support invite commission configuration and display.
WalkthroughAdds invite commission configuration and settlement: new config variables, option handling, top-up model fields and settlement logic, controller responses, and frontend inputs/displays to manage and show invite commission settings. Changes
Sequence DiagramsequenceDiagram
participant User as User
participant TopUp as Top-Up Controller
participant Model as Top-Up Model
participant DB as Database
participant Inviter as Inviter
User->>TopUp: Complete payment / notify (EpayNotify)
TopUp->>Model: Mark top-up successful (update status)
Model->>DB: Update top-up record
DB-->>Model: Acknowledge
TopUp->>Model: SettleInviteCommissionByTradeNo(tradeNo, payerUserID, quota)
Model->>DB: Begin transaction, SELECT ... FOR UPDATE top-up row
DB-->>Model: Row locked, record returned
alt status == success and not already settled
Model->>DB: Resolve inviter (user -> inviter)
DB-->>Model: Inviter info
alt valid inviter and not self-invite
Model->>Model: commission = floor(quota * ratio)
alt commission > 0
Model->>DB: Update inviter.aff_quota, insert aff_history, mark top-up settled with commission
DB-->>Model: Commit
Model-->>TopUp: Settlement success
else Commission <= 0
Model-->>TopUp: Skip (commission zero)
end
else No valid inviter
Model-->>TopUp: Bail out (no-op)
end
else Already settled or invalid status
Model-->>TopUp: Idempotent return (no-op)
end
TopUp-->>User: Finalize response
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
web/src/pages/Setting/Operation/SettingsCreditLimit.jsx (1)
172-208: Consider using Chinese translations for consistency with existing UI labels.The new labels use English text wrapped in
t():
t('Enable invite commission')t('Invite commission ratio')t('When enabled, inviter receives commission after invitee topup')t('Use a decimal between 0 and 1, e.g. 0.1 means 10%')Other labels in this file use Chinese text (e.g.,
t('新用户初始额度'),t('请求预扣费额度')). For consistency with the existing UI, consider using Chinese labels or ensuring these translation keys exist in the i18n files.The functional implementation is correct:
- InputNumber has proper min/max constraints matching backend validation
- Conditional
disabledstate based onInviteCommissionEnabledis good UX- Null coalescing with
value ?? ''prevents undefined values💡 Suggested translation keys for consistency
<Form.Switch - label={t('Enable invite commission')} + label={t('启用邀请返佣')} field={'InviteCommissionEnabled'} extraText={t( - 'When enabled, inviter receives commission after invitee topup', + '启用后,被邀请用户充值时,邀请人可获得返佣', )} ... /> ... <Form.InputNumber - label={t('Invite commission ratio')} + label={t('邀请返佣比例')} field={'InviteCommissionRatio'} ... extraText={t( - 'Use a decimal between 0 and 1, e.g. 0.1 means 10%', + '请输入 0 到 1 之间的小数,例如 0.1 表示 10%', )} ... />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/pages/Setting/Operation/SettingsCreditLimit.jsx` around lines 172 - 208, The UI strings for the new invite-commission controls (Form.Switch with field InviteCommissionEnabled and Form.InputNumber with field InviteCommissionRatio) currently use English keys inside t(...); update these to use Chinese translation keys consistent with the rest of this file (or add matching Chinese entries to the i18n resource) — replace t('Enable invite commission'), t('Invite commission ratio'), t('When enabled, inviter receives commission after invitee topup'), and t('Use a decimal between 0 and 1, e.g. 0.1 means 10%') with the appropriate Chinese keys/strings (or ensure those keys exist in i18n) so labels match the existing localization style.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/components/topup/InvitationCard.jsx`:
- Around line 209-216: Replace the hardcoded English strings in the
InvitationCard component with i18n calls: use t() for both branches where
inviteCommissionEnabled and commissionPercent are rendered (replace the literal
"Invite commission is enabled. Ratio: ${commissionPercent}%" and "Invite
commission is disabled" with t() keys, e.g. t('invite.commission.enabled', {
percent: commissionPercent }) and t('invite.commission.disabled')); update the
Badge/Text rendering to pass the translated strings and add the corresponding
keys to your translation files to ensure consistent localization.
---
Nitpick comments:
In `@web/src/pages/Setting/Operation/SettingsCreditLimit.jsx`:
- Around line 172-208: The UI strings for the new invite-commission controls
(Form.Switch with field InviteCommissionEnabled and Form.InputNumber with field
InviteCommissionRatio) currently use English keys inside t(...); update these to
use Chinese translation keys consistent with the rest of this file (or add
matching Chinese entries to the i18n resource) — replace t('Enable invite
commission'), t('Invite commission ratio'), t('When enabled, inviter receives
commission after invitee topup'), and t('Use a decimal between 0 and 1, e.g. 0.1
means 10%') with the appropriate Chinese keys/strings (or ensure those keys
exist in i18n) so labels match the existing localization style.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
common/constants.gocontroller/option.gocontroller/topup.gomodel/option.gomodel/topup.goweb/src/components/settings/OperationSetting.jsxweb/src/components/topup/InvitationCard.jsxweb/src/components/topup/index.jsxweb/src/pages/Setting/Operation/SettingsCreditLimit.jsx
| <div className='flex items-start gap-2'> | ||
| <Badge dot type={inviteCommissionEnabled ? 'success' : 'warning'} /> | ||
| <Text type='tertiary' className='text-sm'> | ||
| {inviteCommissionEnabled | ||
| ? `Invite commission is enabled. Ratio: ${commissionPercent}%` | ||
| : 'Invite commission is disabled'} | ||
| </Text> | ||
| </div> |
There was a problem hiding this comment.
Internationalization missing for commission status text.
The text strings on lines 213-214 are hardcoded in English, while the rest of the component uses the t() function for internationalization. This will result in mixed-language content for non-English users.
🌐 Proposed fix to use i18n
<Text type='tertiary' className='text-sm'>
{inviteCommissionEnabled
- ? `Invite commission is enabled. Ratio: ${commissionPercent}%`
- : 'Invite commission is disabled'}
+ ? t('邀请返佣已启用,返佣比例:') + `${commissionPercent}%`
+ : t('邀请返佣已禁用')}
</Text>Note: Please verify that the i18n keys are added to the translation files. The suggested Chinese text is illustrative—adjust to match your existing terminology.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <div className='flex items-start gap-2'> | |
| <Badge dot type={inviteCommissionEnabled ? 'success' : 'warning'} /> | |
| <Text type='tertiary' className='text-sm'> | |
| {inviteCommissionEnabled | |
| ? `Invite commission is enabled. Ratio: ${commissionPercent}%` | |
| : 'Invite commission is disabled'} | |
| </Text> | |
| </div> | |
| <div className='flex items-start gap-2'> | |
| <Badge dot type={inviteCommissionEnabled ? 'success' : 'warning'} /> | |
| <Text type='tertiary' className='text-sm'> | |
| {inviteCommissionEnabled | |
| ? t('邀请返佣已启用,返佣比例:') + `${commissionPercent}%` | |
| : t('邀请返佣已禁用')} | |
| </Text> | |
| </div> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@web/src/components/topup/InvitationCard.jsx` around lines 209 - 216, Replace
the hardcoded English strings in the InvitationCard component with i18n calls:
use t() for both branches where inviteCommissionEnabled and commissionPercent
are rendered (replace the literal "Invite commission is enabled. Ratio:
${commissionPercent}%" and "Invite commission is disabled" with t() keys, e.g.
t('invite.commission.enabled', { percent: commissionPercent }) and
t('invite.commission.disabled')); update the Badge/Text rendering to pass the
translated strings and add the corresponding keys to your translation files to
ensure consistent localization.
fix: align Vertex content fetch flow with Gemini and handle base64
fix: vertex ai video proxy and task polling improvements
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.github/workflows/docker-image-auto.yml (1)
66-67: Consider enabling provenance and SBOM for supply chain security.Disabling
provenanceandsbomremoves attestations that help verify image integrity and generate Software Bill of Materials. If disabled intentionally for compatibility or performance reasons, this is fine. Otherwise, enabling these features strengthens supply chain security.- provenance: false - sbom: false + provenance: true + sbom: true🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/docker-image-auto.yml around lines 66 - 67, Enable supply-chain attestations by setting the GitHub Actions image build options provenance: true and sbom: true (replace the current false values for the provenance and sbom keys); if they were disabled intentionally, add a brief inline comment explaining the compatibility/performance reason so reviewers know the decision is deliberate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In @.github/workflows/docker-image-auto.yml:
- Around line 66-67: Enable supply-chain attestations by setting the GitHub
Actions image build options provenance: true and sbom: true (replace the current
false values for the provenance and sbom keys); if they were disabled
intentionally, add a brief inline comment explaining the
compatibility/performance reason so reviewers know the decision is deliberate.
Summary by CodeRabbit
New Features
Chores