fengsilin
b2cb7bcf60
feat: record chat and upstream ids in usage logs
1 week ago
fengsilin
332d5a62f2
feat: support codex api key credentials
1 week ago
fengsilin
1c0898257c
feat: add redemption remarks
1 week ago
fengsilin
d8272e7707
feat(channel): 添加渠道"对外名称"(public_name)字段
为 Channel 模型新增 public_name 字段,让管理员可以为每个渠道
设置用户可见的友好名称(如"标准通道"、"高速通道"),替代前端
硬编码的"通道一/二/三"。Playground 通道选择器展示对外名称,
"渠道"统一改为"通道"。新建渠道时对外名称必填,编辑时可选。
Co-Authored-By: Claude <noreply@anthropic.com>
1 week ago
fengsilin
73d10b5799
feat: 错误日志记录上游 request-id 和响应体,Playground 渠道路由改为 header 传递
- 错误日志新增 upstream_request_id(从 Anthropic/OpenAI 响应 header 提取)和 upstream_body(截断 2KB)
- 修复 RelayErrorHandler 内部 WithOpenAIError/NewOpenAIError 分支丢失上游字段的 bug
- Playground 渠道和分组改为通过 X-Channel-Id/X-Group header 传递,而非 body 字段
- Distributor 中间件支持从 header 回退读取 channel_id 和 group
Co-Authored-By: Claude <noreply@anthropic.com>
1 week ago
fengsilin
74cc8c0d56
feat(playground): 添加渠道选择功能,支持指定渠道体验模型
- 新增 /api/user/model_channels 接口,返回模型可用渠道及默认渠道
- Playground 设置面板添加渠道选择下拉框
- Distribute 中间件支持从请求体读取 channel_id 指定渠道
- 支持 URL 参数 ?model=xxx 直接选择模型
Co-Authored-By: Claude <noreply@anthropic.com>
1 week ago
fengsilin
a34d44a824
fix(user): 修复从节点同步用户余额显示为 0 的问题
同步用户(synced)的实际余额存储在 synced_quota 字段,
但用户列表/详情接口返回的是 quota 字段(值为 0)。
新增 ApplySyncedQuota 方法,在 API 返回前将 synced_quota
赋值给 quota,使前端能正确显示余额。
同时优化 GetUserModels:map 去重替代 O(n) 线性扫描,
禁用模型查询移至 model 层,新增 StringsSubtract 工具函数。
Co-Authored-By: Claude <noreply@anthropic.com>
1 week ago
fengsilin
967309fb56
feat: 添加邮箱后缀注册额度规则功能
管理员可在用户管理页面配置「邮箱后缀→初始额度」映射规则,
用户注册时根据邮箱后缀自动匹配并发放对应额度(替代默认额度)。
- 新增 email_quota_rule 数据表 + CRUD API(管理员权限)
- 内存缓存匹配,启动时加载,增删改时刷新
- 注册流程 Insert/InsertWithTx/FinalizeOAuthUserCreation 同步支持
- 前端用户管理页新增 Tab 展示规则管理卡片
- 含 24 个测试(model 16 + controller 8)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 week ago
fengsilin
1912dd3b72
feat: 添加图片验证码功能,防止脚本批量注册
- 后端:新增 GET /api/captcha 接口,使用 base64Captcha 生成图片验证码
- 后端:发送邮箱验证码时校验图片验证码(CaptchaEnabled 开关控制)
- 前端:注册表单邮箱验证码前增加图片验证码输入,支持点击刷新
- 管理后台:系统设置新增「图片验证码」开关
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2 weeks ago
fengsilin
934b4b10a7
feat: 法律文档双语配置(中/英)+ 精简语言支持至中英双语
- LegalSettings 字段拆分为 _zh/_en 双语对
- API 支持 ?lang= 参数返回对应语言内容
- 后台设置页每个文档配语言切换按钮(中文/English)
- 前端页面根据 UI 语言自动请求对应内容
- 移除 fr/ru/ja/vi/zh-TW 语言支持
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2 weeks ago
fengsilin
1cc75aa9a2
feat: 服务条款和使用政策页面,支持后台 Markdown 配置
复用现有 LegalSettings 模式,新增 TermsOfService 和 UsagePolicy 字段,
添加 /terms 和 /usage-policy 前端页面及 API 端点。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2 weeks ago
fengsilin
749064932c
feat: 新增 PUT /api/vendors/reorder 和 /api/models/reorder 批量排序接口
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2 weeks ago
fengsilin
3a29f3772f
feat(channel): 添加模型默认通道功能,支持优先路由和卡片标识
- 新增 is_default 字段和缓存层,支持管理员为模型指定默认通道
- Distribute 中间件优先级调整:Token 指定 → 默认通道 → 亲和性 → 随机
- 模型定价卡片和详情弹窗展示默认通道 amber 标识
- 管理后台定价页面新增星标切换默认通道
- 新增 set_default / clear_default API 和 6 个单元测试
- 简化卡片价格显示(移除内联缓存价格,改为详情弹窗展示)
Co-Authored-By: Claude <noreply@anthropic.com>
2 weeks ago
fengsilin
93e331b624
feat: 支持 LOGO_FILE_PATH 环境变量指定本地 Logo,优化定价与语言设置
- 新增 LOGO_FILE_PATH 环境变量,优先级高于数据库配置,支持本地文件服务
- 渠道定价高级字段(缓存/图片/音频)不再回退全局默认值,未设置直接返回 0
- 缓存价格单位从表头移到具体价格值,新增渠道 ID 复制功能
- 修复默认语言在用户已有偏好时仍被覆盖的问题
- img 标签统一添加 referrerPolicy/crossOrigin 防止跨域问题
- 新增缓存倍率和最小余额阈值的详细说明文本
Co-Authored-By: Claude <noreply@anthropic.com>
2 weeks ago
fengsilin
f0f0215b20
fix(pricing): 修复缓存倍率写入默认值1和缓存创建token丢失
1. CopyGlobalPricing 检查 ratio 查找的 bool 返回值,未找到时写 0
而非写入 fallback 值 1,避免覆盖全局正确的 0.1
2. Claude 响应使用 GetCacheCreationTotalTokens() 替代直接读
CacheCreationInputTokens,兼容新版本子对象格式
3. 新增 GetAudioRatioV2/GetAudioCompletionRatioV2 带 bool 返回
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2 weeks ago
fengsilin
00058cd671
refactor(channel-pricing): 提取辅助方法消除重复代码,修复缓存一致性
- 提取 PriceData.ApplyChannelPricingRatios 消除 ModelPriceHelper 和
UpdatePriceDataForChannelPricing 中重复的 ~30 行比率回退逻辑
- 提取 ChannelPricing.ApplyFields 消除 controller 中 4 处相同的字段赋值
- 提取 setCache/removeCache 辅助函数统一写穿透缓存操作
- 将 claudeCacheCreation1hMultiplier 常量移至 types 包避免循环依赖
- 修复 BatchUpsertChannelPricing 成功后未刷新内存缓存的 bug
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2 weeks ago
fengsilin
9eb58c684e
feat: 后台设置默认语言
管理员可在系统设置页面配置全局默认语言,未登录用户和未设置
语言偏好的已登录用户将强制使用该语言,忽略浏览器语言检测。
- common/constants.go: 新增 DefaultLanguage 变量
- model/option.go: 新增 DefaultLanguage option handler
- controller/misc.go: /api/status 暴露 default_language
- SystemSetting.jsx: 添加语言下拉框到通用设置
- PageLayout.jsx: 未登录用户应用默认语言
- UserContext.jsx: 无偏好用户回退到默认语言
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2 weeks ago
fengsilin
235f7c6e5f
refactor(channel-pricing): 提取 ParseTagIds 辅助函数 + 移除调试 console.log
- 将 tag ID 解析逻辑提取为 model.ParseTagIds,消除 model 层和 controller 层重复代码
- 统一 TrimSpace 处理(之前 controller 版本漏了)
- 移除 ChannelPricingView 残留的 console.log('Expanded keys:')
- 删除多余空行
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3 weeks ago
fengsilin
646f37dd4b
feat(channel-pricing): Controller 扩展 API 支持新字段 + 输入校验 + 操作日志
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3 weeks ago
fengsilin
b514a0798b
refactor(payment): 合并微信/支付宝支付重复代码,删除冗余文件
- 提取通用 calcPayMoney/calcMinTopup 函数,消除微信和支付宝控制器中的重复计费逻辑
- 合并 RechargeAlipay/RechargeWechat 为 rechargeByQRCodePayment 内部函数,删除 model/topup_alipay.go
- 复用已有的 wrapAsPEM 替换支付宝专用的 wrapAlipayPublicKey
- 删除被 QRCodePayModal 替代的 WechatPayQRCodeModal.jsx
- 修复 controller/topup.go 中支付宝代码块的缩进错误
净减 264 行代码。
Co-Authored-By: Claude <noreply@anthropic.com>
3 weeks ago
fengsilin
e8ade3abae
feat(payment): 集成支付宝当面付扫码支付 + 补全前端 i18n 硬编码中文
支付宝支付:
- 后端:新增 topup_alipay.go、payment_alipay.go,实现当面付(扫码支付)下单、
回调验签、订单状态查询完整流程,支持 RSA2 签名
- 前端:新增 QRCodePayModal 通用二维码支付弹窗(泛化微信支付弹窗)、
SettingsPaymentGatewayAlipay 管理配置页面、充值流程接入支付宝
- 充值历史:管理员视图新增用户邮箱列,后端 fillTopUpEmails 批量填充
i18n 补全:
- 54 个缺失翻译 key 添加到全部 7 个 locale 文件(zh-CN/zh-TW/en/fr/ja/ru/vi)
- 涵盖渠道名称、仪表盘标签、兑换码状态、控制台时间筛选、Playground 错误消息、
Dashboard 设置页面提示等
- 14 个源码文件中约 31 处 showError/showSuccess/showWarning 硬编码中文改用 t()
- ChannelsColumnDefs、helpers、services 中散落的硬编码中文统一国际化
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3 weeks ago
fengsilin
cf2a0a7992
fix(payment): 修复微信支付集成多项问题
- 修复订单号超 32 字符限制(微信支付要求),改用时间戳+随机字符格式
- 修复密钥解析:添加 wrapAsPEM 兼容 PEM/Base64/DER 多种输入格式
- 修复前端:RechargeCard 未识别 enableWechatTopUp 导致充值表单不显示
- 修复前端:支付按钮禁用逻辑未区分 epay/wechat_pay
- 移除状态轮询接口的 CriticalRateLimit 防止 429
- 过滤未启用易支付的旧支付方法避免混淆
- 修复 SiLinkedin 图标不存在导致构建失败
- 简化 webhook 冗余条件判断
- 添加密钥解析相关测试
Co-Authored-By: Claude <noreply@anthropic.com>
3 weeks ago
fengsilin
00e266cd77
feat(payment): 集成微信支付 Native(扫码支付)V3 API
完整实现微信支付充值和订阅购买功能,支持配置热更新、二维码扫码支付、
回调验签、订单状态轮询,以及管理后台支付网关设置。
后端:
- 新增微信支付 V3 客户端(支持 Base64/文件路径两种密钥加载)
- Native 下单、回调处理、订单状态查询 API
- 充值订单幂等完成(事务+行锁)
- 订阅购买支持微信支付
- 配置变更自动重置客户端
- 提取 createWechatNativeOrder 消除重复下单逻辑
前端:
- 二维码扫码弹窗(含倒计时、自动轮询状态)
- 微信支付设置页面(AppID、商户号、密钥等 12 项配置)
- 充值页集成微信支付流程
依赖:go-pay/gopay v1.5.117
Co-Authored-By: Claude <noreply@anthropic.com>
3 weeks ago
fengsilin
b693a733ba
feat(region-sync): 批量查询用户余额接口,优化同步性能
RunQuotaSync 从逐个查询改为批量查询(每批500个),
减少 Master 节点 API 调用次数,提升同步效率。
新增:
- BatchQueryUserQuota 控制器接口
- BatchQueryQuota 客户端方法
- QuotaEntry/BatchQueryQuotaRequest/Response 类型
附带 update-image.sh 部署脚本。
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3 weeks ago
fengsilin
296edf0f71
fix: 移植上游关键 bug 修复
从 QuantumNous/new-api 上游移植以下修复:
- fix(ssrf): 加固视频代理和 MJ 图片代理的 SSRF 防护,FetchModels 提权至 RootAuth
- fix(claude): 流式断流时不再整份覆盖 usage,保留 cache 计费字段
- fix(pricing): 定价接口增加用户可用分组过滤
- fix(ratio): compact 模型优先匹配精确定价再回退通配符
- fix(ali): 接受 task polling 返回的字符串类型 usage 值
- fix(gemini): 从 URL 路径 :streamGenerateContent 检测流式请求
- fix(zhipu_4v): coding plan 图片生成使用正确的 OpenAI endpoint
- fix(openai): MessageImageUrl.Detail 字段添加 omitempty
- fix(channel-affinity): skip_retry_on_failure 配置项为 false 时不再丢失
- fix(document-renderer): 使用 useMemo 替代 useState 处理 HTML payload
- fix(fetch-setting): ApplyIPFilterForDomain 默认值改为 true
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3 weeks ago
fengsilin
9d4a595465
feat(region-sync): Master→Slave 配置同步、热更新与前端修复
- 新增 GET /api/internal/sync/config 接口,Master 下发 MinBalanceThreshold、MaxRetryCount、SyncBatchSize、SyncIntervalSeconds
- Slave 每 5 分钟从 Master 拉取配置并持久化到本地数据库,确保重启不丢失
- 统一 startWorker 支持动态间隔,同步间隔前端修改后无需重启立即生效
- 主节点地址从 TagInput 改为 Form.Input,修复 JSON 数组格式问题
- stringToArray 兼容 JSON 数组和换行分隔两种格式
- 清理根目录测试脚本(已迁移到 test-scripts/)
Co-Authored-By: Claude <noreply@anthropic.com>
4 weeks ago
fengsilin
dc20782918
fix(region-sync): 修复 Settle/SyncManager 竞争条件并优化并发安全
- 新增 settled 状态,防止 SyncManager 在 PreConsume/Settle 之间同步未结算记录
- Settle 使用 AdjustSyncedQuota(增量 gorm.Expr)替代 UpdateSyncedQuota(绝对值),修复并发覆写
- 网络失败时标记所有记录为 failed 并增加 retry_count,避免无限重试
- 新增 ArchiveStalePendingRecords 定时清理崩溃请求的 pending 记录
- 简化 IsSyncedUser/IsLocalUser 移除冗余 id 参数
- Dockerfile 切换华为云 Go 镜像,移除不兼容的 GOEXPERIMENT=greenteagc
Co-Authored-By: Claude <noreply@anthropic.com>
4 weeks ago
fengsilin
1cecd5349d
feat: 跨区域配额同步(Master-Slave Region Sync)
实现 Master-Slave 架构的跨区域用户和配额同步功能,支持国内主节点与
海外从节点之间的用户创建推送、余额同步、预扣费批量回传。
主要变更:
- 新增 region_sync 服务层(SyncManager/SyncClient/推送逻辑)
- User 模型扩展 Source/RemoteUserId/SyncedQuota/LastSyncAt 字段
- BillingSession 支持 SyncedUserFunding 资金来源
- 新增 SyncAuth 中间件(X-Sync-API-Key + 常量时间比较)
- 新增 PendingSyncRecord/QuotaSyncLog 数据模型
- 前端新增区域同步配置面板
- 支持 SESSION_NAME 环境变量避免多节点 cookie 冲突
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4 weeks ago
fengsilin
62737d3f8c
feat: 添加模型详情页渠道价格展示 & 优化筛选行布局
- 新增 API 端点获取模型在各渠道的定价信息,支持全局价格回退
- 在模型详情侧边栏添加渠道价格卡片,显示所有支持该模型的渠道
- 优化 HorizontalFilterRow 组件,改用 flex-wrap 自动换行布局
- 隐藏数量为 0 的模型类型筛选项
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 month ago
fengsilin
bfa7cc7b97
feat(token): support dynamic channel specification via colon separator
- Add support for sk-{key}:{channelId} format to specify channel dynamically
- Remove BoundChannelId field and related code
- All users can now specify channels, not just admins
- Add model validation when channel is specified
- Remove bound channel UI from token management
Breaking change: tokens can no longer be bound to channels at creation time.
Use sk-{key}:{channelId} format instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 month ago
fengsilin
15a99da48e
fix: channel pricing not working correctly
This PR fixes three issues:
1. Token bound_channel_id not updating: Add bound field to Update() method
2. Channel pricing quota_type detection: Use QuotaTypeByCall constant instead of magic number 1
3. Log display for ratio-based pricing: Set ModelPrice=-1 for ratio-based pricing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 month ago
fengsilin
352806c099
feat: add dedicated API for user channel binding selection
Add a new /api/user/channels endpoint that returns only enabled channels
with non-sensitive fields (id, name, type, remark) for token channel binding.
Update EditTokenModal to use this endpoint and display remark instead of ID
in the channel dropdown.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 month ago
fengsilin
ffddf58e78
feat: support bound_channel_id in token CRUD
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 month ago
fengsilin
ab66594d9e
feat: add PricingTag CRUD controller
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 month ago
fengsilin
447ccd09b2
feat: add ChannelPricing CRUD controller
- GetAllChannelPricing: get all channel pricings with pagination
- GetChannelPricingByModel: get pricings for a specific model
- CreateChannelPricing: create or update channel pricing
- BatchCreateChannelPricing: batch create/update pricings
- DeleteChannelPricing: delete channel pricing
- CopyGlobalPricing: copy global pricing from ratio_setting to channel
- GetChannelPricingWithTags: get pricings with tag details
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 month ago
winter
08164cd0ae
fix
2 months ago