feat(admin): 新增 CRS 同步预览和账号选择功能
- 后端新增 PreviewFromCRS 接口,允许用户先预览 CRS 中的账号 - 后端支持在同步时选择特定账号,不选中的账号将被跳过 - 前端重构 SyncFromCrsModal 为三步向导:输入凭据 → 预览账号 → 执行同步 - 改进表单无障碍性:添加 for/id 关联和 required 属性 - 修复 Back 按钮返回时的状态清理 - 新增 buildSelectedSet 和 shouldCreateAccount 的单元测试 - 完整的向后兼容性:旧客户端不发送 selected_account_ids 时行为不变
This commit is contained in:
@@ -424,10 +424,17 @@ type TestAccountRequest struct {
|
||||
}
|
||||
|
||||
type SyncFromCRSRequest struct {
|
||||
BaseURL string `json:"base_url" binding:"required"`
|
||||
Username string `json:"username" binding:"required"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
SyncProxies *bool `json:"sync_proxies"`
|
||||
BaseURL string `json:"base_url" binding:"required"`
|
||||
Username string `json:"username" binding:"required"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
SyncProxies *bool `json:"sync_proxies"`
|
||||
SelectedAccountIDs []string `json:"selected_account_ids"`
|
||||
}
|
||||
|
||||
type PreviewFromCRSRequest struct {
|
||||
BaseURL string `json:"base_url" binding:"required"`
|
||||
Username string `json:"username" binding:"required"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
}
|
||||
|
||||
// Test handles testing account connectivity with SSE streaming
|
||||
@@ -466,10 +473,11 @@ func (h *AccountHandler) SyncFromCRS(c *gin.Context) {
|
||||
}
|
||||
|
||||
result, err := h.crsSyncService.SyncFromCRS(c.Request.Context(), service.SyncFromCRSInput{
|
||||
BaseURL: req.BaseURL,
|
||||
Username: req.Username,
|
||||
Password: req.Password,
|
||||
SyncProxies: syncProxies,
|
||||
BaseURL: req.BaseURL,
|
||||
Username: req.Username,
|
||||
Password: req.Password,
|
||||
SyncProxies: syncProxies,
|
||||
SelectedAccountIDs: req.SelectedAccountIDs,
|
||||
})
|
||||
if err != nil {
|
||||
// Provide detailed error message for CRS sync failures
|
||||
@@ -480,6 +488,28 @@ func (h *AccountHandler) SyncFromCRS(c *gin.Context) {
|
||||
response.Success(c, result)
|
||||
}
|
||||
|
||||
// PreviewFromCRS handles previewing accounts from CRS before sync
|
||||
// POST /api/v1/admin/accounts/sync/crs/preview
|
||||
func (h *AccountHandler) PreviewFromCRS(c *gin.Context) {
|
||||
var req PreviewFromCRSRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.BadRequest(c, "Invalid request: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
result, err := h.crsSyncService.PreviewFromCRS(c.Request.Context(), service.SyncFromCRSInput{
|
||||
BaseURL: req.BaseURL,
|
||||
Username: req.Username,
|
||||
Password: req.Password,
|
||||
})
|
||||
if err != nil {
|
||||
response.InternalError(c, "CRS preview failed: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, result)
|
||||
}
|
||||
|
||||
// Refresh handles refreshing account credentials
|
||||
// POST /api/v1/admin/accounts/:id/refresh
|
||||
func (h *AccountHandler) Refresh(c *gin.Context) {
|
||||
|
||||
Reference in New Issue
Block a user