feat(admin): 新增 CRS 同步预览和账号选择功能

- 后端新增 PreviewFromCRS 接口,允许用户先预览 CRS 中的账号
- 后端支持在同步时选择特定账号,不选中的账号将被跳过
- 前端重构 SyncFromCrsModal 为三步向导:输入凭据 → 预览账号 → 执行同步
- 改进表单无障碍性:添加 for/id 关联和 required 属性
- 修复 Back 按钮返回时的状态清理
- 新增 buildSelectedSet 和 shouldCreateAccount 的单元测试
- 完整的向后兼容性:旧客户端不发送 selected_account_ids 时行为不变
This commit is contained in:
QTom
2026-02-09 10:38:26 +08:00
parent 149e4267cd
commit 5e0d789440
13 changed files with 653 additions and 51 deletions

View File

@@ -282,6 +282,34 @@ func (r *accountRepository) GetByCRSAccountID(ctx context.Context, crsAccountID
return &accounts[0], nil
}
func (r *accountRepository) ListCRSAccountIDs(ctx context.Context) (map[string]int64, error) {
rows, err := r.sql.QueryContext(ctx, `
SELECT id, extra->>'crs_account_id'
FROM accounts
WHERE deleted_at IS NULL
AND extra->>'crs_account_id' IS NOT NULL
AND extra->>'crs_account_id' != ''
`)
if err != nil {
return nil, err
}
defer func() { _ = rows.Close() }()
result := make(map[string]int64)
for rows.Next() {
var id int64
var crsID string
if err := rows.Scan(&id, &crsID); err != nil {
return nil, err
}
result[crsID] = id
}
if err := rows.Err(); err != nil {
return nil, err
}
return result, nil
}
func (r *accountRepository) Update(ctx context.Context, account *service.Account) error {
if account == nil {
return nil