swagger

移除 merchant

swagger

改造首页内容为通用后台管理系统定位

- 修改首页标题从 'LINUX DO Credit' 改为 'Modern Platform'
- 更新副标题为 '为二次开发而生'
- 更新首页描述为通用平台的特点
- 更新首页特性标签为 '开箱即用、高度可扩展、工业级基建'
- 修改展示卡片为技术栈和二次开发相关
- 更新开发者示例代码为通用的注册和 API Key 获取示例
- 更新页脚品牌名为 'Modern Platform'
- 调整页脚导航链接为通用平台相关内容

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

去除遗留

裁剪
移除 /api/v1/user/pay-key 相关代码

- 删除后端 UpdatePayKey 处理器函数和 UpdatePayKeyRequest 结构体
- 删除 User 模型中的 PayKey 字段
- 删除 User.VerifyPayKey 方法
- 删除 EncryptPayKeyFailed 错误常量
- 删除 /api/v1/user/pay-key PUT 路由
- 删除 OAuth 返回中的 IsPayKey 字段
- 删除前端 UserService.updatePayKey 方法
- 删除前端所有支付密钥 UI 和逻辑
- 更新相关的导出和注释

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

去除遗留

api 修正

系统配置

前端裁剪

后端裁剪

init
This commit is contained in:
ryan
2026-06-07 15:32:14 +08:00
parent 8a782525de
commit 48d414e197
180 changed files with 1538 additions and 27463 deletions
+3 -63
View File
@@ -17,31 +17,16 @@ limitations under the License.
package task
const (
UpdateUserGamificationScoresTask = "user:gamification:update_scores_task"
UpdateSingleUserGamificationScoreTask = "user:gamification:update_single_score_task"
AutoRefundExpiredDisputesTask = "dispute:auto_refund_expired"
AutoRefundSingleDisputeTask = "dispute:auto_refund_single"
MerchantPaymentNotifyTask = "payment:merchant_notify"
SyncOrdersToClickHouseTask = "order:sync_to_clickhouse"
RefundExpiredRedEnvelopesTask = "redenvelope:refund_expired"
CleanupUnusedUploadsTask = "upload:cleanup_unused"
SettlePendingPaymentsTask = "order:settle_pending_payments"
CleanupUnusedUploadsTask = "upload:cleanup_unused"
)
const (
QueueWhitelistOnly = "whitelist_only"
QueueWebhook = "webhook"
QueueDefault = "default"
QueueDefault = "default"
)
// 管理员可下发的任务类型标识
const (
TaskTypeOrderSync = "order_sync"
TaskTypeUserGamification = "user_gamification"
TaskTypeDisputeRefund = "dispute_auto_refund"
TaskTypeRedEnvelopeRefund = "redenvelope_auto_refund"
TaskTypeCleanupUploads = "cleanup_unused_uploads"
TaskTypeSettlePending = "settle_pending_payments"
TaskTypeCleanupUploads = "cleanup_unused_uploads"
)
// TaskMeta 任务元数据
@@ -57,42 +42,6 @@ type TaskMeta struct {
// DispatchableTasks 可下发的任务列表
var DispatchableTasks = []TaskMeta{
{
Type: TaskTypeOrderSync,
AsynqTask: SyncOrdersToClickHouseTask,
Name: "订单同步",
Description: "同步订单数据到 ClickHouse",
SupportsTime: true,
MaxRetry: 5,
Queue: QueueDefault,
},
{
Type: TaskTypeUserGamification,
AsynqTask: UpdateSingleUserGamificationScoreTask,
Name: "用户积分更新",
Description: "更新用户的点数积分",
SupportsTime: false,
MaxRetry: 5,
Queue: QueueWhitelistOnly,
},
{
Type: TaskTypeDisputeRefund,
AsynqTask: AutoRefundExpiredDisputesTask,
Name: "争议自动退款",
Description: "处理过期争议的自动退款",
SupportsTime: false,
MaxRetry: 5,
Queue: QueueDefault,
},
{
Type: TaskTypeRedEnvelopeRefund,
AsynqTask: RefundExpiredRedEnvelopesTask,
Name: "红包自动退款",
Description: "处理过期红包的自动退款",
SupportsTime: false,
MaxRetry: 5,
Queue: QueueDefault,
},
{
Type: TaskTypeCleanupUploads,
AsynqTask: CleanupUnusedUploadsTask,
@@ -102,15 +51,6 @@ var DispatchableTasks = []TaskMeta{
MaxRetry: 3,
Queue: QueueDefault,
},
{
Type: TaskTypeSettlePending,
AsynqTask: SettlePendingPaymentsTask,
Name: "延迟到账结算",
Description: "结算到期的延迟到账订单,将在途资金转入可用余额",
SupportsTime: false,
MaxRetry: 5,
Queue: QueueDefault,
},
}
// GetTaskMeta 根据任务类型获取元数据
-50
View File
@@ -53,46 +53,6 @@ func StartScheduler() error {
},
)
// 用户积分更新任务
if _, err = scheduler.Register(
config.Config.Scheduler.UpdateUserGamificationScoresTaskCron,
asynq.NewTask(task.UpdateUserGamificationScoresTask, nil),
asynq.Queue(task.QueueWhitelistOnly),
asynq.MaxRetry(5),
asynq.Unique(23*time.Hour),
); err != nil {
return
}
// 争议自动退款任务
if _, err = scheduler.Register(
config.Config.Scheduler.AutoRefundExpiredDisputesTaskCron,
asynq.NewTask(task.AutoRefundExpiredDisputesTask, nil),
asynq.MaxRetry(5),
asynq.Unique(23*time.Hour),
); err != nil {
return
}
// 订单同步任务
if _, err = scheduler.Register(
config.Config.Scheduler.SyncOrdersToClickHouseTaskCron,
asynq.NewTask(task.SyncOrdersToClickHouseTask, nil),
asynq.MaxRetry(10),
asynq.Unique(23*time.Hour),
); err != nil {
return
}
// 红包过期退款任务
if _, err = scheduler.Register(
config.Config.Scheduler.RefundExpiredRedEnvelopesTaskCron,
asynq.NewTask(task.RefundExpiredRedEnvelopesTask, nil),
asynq.Unique(23*time.Hour),
); err != nil {
return
}
// 清理未使用的上传文件任务
if _, err = scheduler.Register(
config.Config.Scheduler.CleanupUnusedUploadsTaskCron,
@@ -103,16 +63,6 @@ func StartScheduler() error {
return
}
// 延迟到账结算任务
if _, err = scheduler.Register(
config.Config.Scheduler.SettlePendingPaymentsTaskCron,
asynq.NewTask(task.SettlePendingPaymentsTask, nil),
asynq.Unique(55*time.Minute),
asynq.MaxRetry(3),
); err != nil {
return
}
// 启动调度器
err = scheduler.Run()
})
+1 -44
View File
@@ -17,18 +17,10 @@ limitations under the License.
package worker
import (
"log"
"math/rand"
"strings"
"time"
"github.com/hibiken/asynq"
"github.com/linux-do/credit/internal/apps/dispute"
"github.com/linux-do/credit/internal/apps/order"
"github.com/linux-do/credit/internal/apps/payment"
"github.com/linux-do/credit/internal/apps/redenvelope"
"github.com/linux-do/credit/internal/apps/upload"
"github.com/linux-do/credit/internal/apps/user"
"github.com/linux-do/credit/internal/config"
"github.com/linux-do/credit/internal/task"
)
@@ -42,46 +34,13 @@ func StartWorker() error {
ShutdownTimeout: 3 * time.Minute,
Queues: buildQueuesFromConfig(),
StrictPriority: config.Config.Worker.StrictPriority,
RetryDelayFunc: func(n int, err error, t *asynq.Task) time.Duration {
log.Printf("[RetryDelayFunc] 任务类型: %s, 重试次数: %d, 错误: %v", t.Type(), n, err)
// 针对积分更新任务使用更长的重试间隔 + 随机抖动
if t.Type() == task.UpdateSingleUserGamificationScoreTask {
var baseDelay time.Duration
if err != nil && strings.Contains(err.Error(), "429") {
baseDelay = 120 * time.Second
} else {
baseDelay = 60 * time.Second
}
// 指数退避:n=0 时 delay=baseDelay,之后翻倍
delay := baseDelay * time.Duration(1<<uint(n))
if delay > 30*time.Minute {
delay = 30 * time.Minute
}
// delay ~ 2*delay
if delay > 0 {
jitter := time.Duration(rand.Int63n(int64(delay)))
delay += jitter
}
return delay
}
return asynq.DefaultRetryDelayFunc(n, err, t)
},
},
)
// 注册任务处理器
mux := asynq.NewServeMux()
mux.Use(taskLoggingMiddleware)
mux.HandleFunc(task.UpdateUserGamificationScoresTask, user.HandleUpdateUserGamificationScores)
mux.HandleFunc(task.UpdateSingleUserGamificationScoreTask, user.HandleUpdateSingleUserGamificationScore)
mux.HandleFunc(task.AutoRefundExpiredDisputesTask, dispute.HandleAutoRefundExpiredDisputes)
mux.HandleFunc(task.AutoRefundSingleDisputeTask, dispute.HandleAutoRefundSingleDispute)
mux.HandleFunc(task.MerchantPaymentNotifyTask, payment.HandleMerchantPaymentNotify)
mux.HandleFunc(task.SyncOrdersToClickHouseTask, order.HandleSyncOrdersToClickHouse)
mux.HandleFunc(task.RefundExpiredRedEnvelopesTask, redenvelope.HandleRefundExpiredRedEnvelopes)
mux.HandleFunc(task.CleanupUnusedUploadsTask, upload.HandleCleanupUnusedUploads)
mux.HandleFunc(task.SettlePendingPaymentsTask, order.HandleSettlePendingPayments)
// 启动服务器
return asynqServer.Run(mux)
@@ -103,9 +62,7 @@ func buildQueuesFromConfig() map[string]int {
// 如果配置为空,使用默认队列
if len(queues) == 0 {
queues = map[string]int{
task.QueueWebhook: 10,
task.QueueWhitelistOnly: 5,
task.QueueDefault: 1,
task.QueueDefault: 1,
}
}