Skip to content

Commit d4dd5ea

Browse files
authored
feat: 分组密钥检查增加状态选项 (#86)
1 parent 1c658fa commit d4dd5ea

File tree

5 files changed

+60
-15
lines changed

5 files changed

+60
-15
lines changed

internal/handler/key_handler.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ type GroupIDRequest struct {
6262
GroupID uint `json:"group_id" binding:"required"`
6363
}
6464

65+
// ValidateGroupKeysRequest defines the payload for validating keys in a group.
66+
type ValidateGroupKeysRequest struct {
67+
GroupID uint `json:"group_id" binding:"required"`
68+
Status string `json:"status,omitempty"`
69+
}
70+
6571
// AddMultipleKeys handles creating new keys from a text block within a specific group.
6672
func (s *Server) AddMultipleKeys(c *gin.Context) {
6773
var req KeyTextRequest
@@ -258,12 +264,18 @@ func (s *Server) TestMultipleKeys(c *gin.Context) {
258264

259265
// ValidateGroupKeys initiates a manual validation task for all keys in a group.
260266
func (s *Server) ValidateGroupKeys(c *gin.Context) {
261-
var req GroupIDRequest
267+
var req ValidateGroupKeysRequest
262268
if err := c.ShouldBindJSON(&req); err != nil {
263269
response.Error(c, app_errors.NewAPIError(app_errors.ErrInvalidJSON, err.Error()))
264270
return
265271
}
266272

273+
// Validate status if provided
274+
if req.Status != "" && req.Status != models.KeyStatusActive && req.Status != models.KeyStatusInvalid {
275+
response.Error(c, app_errors.NewAPIError(app_errors.ErrValidation, "Invalid status value"))
276+
return
277+
}
278+
267279
groupDB, ok := s.findGroupByID(c, req.GroupID)
268280
if !ok {
269281
return
@@ -275,7 +287,7 @@ func (s *Server) ValidateGroupKeys(c *gin.Context) {
275287
return
276288
}
277289

278-
taskStatus, err := s.KeyManualValidationService.StartValidationTask(group)
290+
taskStatus, err := s.KeyManualValidationService.StartValidationTask(group, req.Status)
279291
if err != nil {
280292
response.Error(c, app_errors.NewAPIError(app_errors.ErrTaskInProgress, err.Error()))
281293
return

internal/services/key_manual_validation_service.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,14 @@ func NewKeyManualValidationService(db *gorm.DB, validator *keypool.KeyValidator,
4141
}
4242

4343
// StartValidationTask starts a new manual validation task for a given group.
44-
func (s *KeyManualValidationService) StartValidationTask(group *models.Group) (*TaskStatus, error) {
44+
func (s *KeyManualValidationService) StartValidationTask(group *models.Group, status string) (*TaskStatus, error) {
4545
var keys []models.APIKey
46-
if err := s.DB.Where("group_id = ?", group.ID).Find(&keys).Error; err != nil {
47-
return nil, fmt.Errorf("failed to get keys for group %s: %w", group.Name, err)
46+
query := s.DB.Where("group_id = ?", group.ID)
47+
if status != "" {
48+
query = query.Where("status = ?", status)
49+
}
50+
if err := query.Find(&keys).Error; err != nil {
51+
return nil, fmt.Errorf("failed to get keys for group %s with status '%s': %w", group.Name, status, err)
4852
}
4953

5054
if len(keys) == 0 {
@@ -59,13 +63,20 @@ func (s *KeyManualValidationService) StartValidationTask(group *models.Group) (*
5963
}
6064

6165
// Run the validation in a separate goroutine
62-
go s.runValidation(group, keys)
66+
go s.runValidation(group, keys, status)
6367

6468
return taskStatus, nil
6569
}
6670

67-
func (s *KeyManualValidationService) runValidation(group *models.Group, keys []models.APIKey) {
68-
logrus.Infof("Starting manual validation for group %s", group.Name)
71+
func (s *KeyManualValidationService) runValidation(group *models.Group, keys []models.APIKey, status string) {
72+
logFields := logrus.Fields{
73+
"group": group.Name,
74+
"status": status,
75+
}
76+
if status == "" {
77+
logFields["status"] = "all"
78+
}
79+
logrus.WithFields(logFields).Info("Starting manual validation")
6980

7081
jobs := make(chan models.APIKey, len(keys))
7182
results := make(chan bool, len(keys))

web/src/api/keys.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,21 @@ export const keysApi = {
175175
},
176176

177177
// 验证分组密钥
178-
async validateGroupKeys(groupId: number): Promise<{
178+
async validateGroupKeys(
179+
groupId: number,
180+
status?: "active" | "invalid"
181+
): Promise<{
179182
is_running: boolean;
180183
group_name: string;
181184
processed: number;
182185
total: number;
183186
started_at: string;
184187
}> {
185-
const res = await http.post("/keys/validate-group", { group_id: groupId });
188+
const payload: { group_id: number; status?: string } = { group_id: groupId };
189+
if (status) {
190+
payload.status = status;
191+
}
192+
const res = await http.post("/keys/validate-group", payload);
186193
return res.data;
187194
},
188195

web/src/components/GlobalTaskProgressBar.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ async function pollOnce() {
4949
let msg = "任务已完成。";
5050
if (task.task_type === "KEY_VALIDATION") {
5151
const result = task.result as import("@/types/models").KeyValidationResult;
52-
msg = `密钥验证完成,处理了 ${result.total_keys} 个密钥,其中 ${result.valid_keys} 个有效,${result.invalid_keys} 个无效`;
52+
msg = `密钥验证完成,处理了 ${result.total_keys} 个密钥,其中 ${result.valid_keys} 个成功,${result.invalid_keys} 个失败。请注意:验证失败并不一定拉黑该密钥,需要失败次数达到阈值才会拉黑`;
5353
} else if (task.task_type === "KEY_IMPORT") {
5454
const result = task.result as import("@/types/models").KeyImportResult;
5555
msg = `密钥导入完成,成功添加 ${result.added_count} 个密钥,忽略了 ${result.ignored_count} 个。`;

web/src/components/keys/KeyTable.vue

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ const moreOptions = [
6767
{ label: "清空所有无效密钥", key: "clearInvalid", props: { style: { color: "#d03050" } } },
6868
{ type: "divider" },
6969
{ label: "验证所有密钥", key: "validateAll" },
70+
{ label: "验证有效密钥", key: "validateActive" },
71+
{ label: "验证无效密钥", key: "validateInvalid" },
7072
];
7173
7274
let testingMsg: MessageReactive | null = null;
@@ -150,7 +152,13 @@ function handleMoreAction(key: string) {
150152
restoreAllInvalid();
151153
break;
152154
case "validateAll":
153-
validateAllKeys();
155+
validateKeys("all");
156+
break;
157+
case "validateActive":
158+
validateKeys("active");
159+
break;
160+
case "validateInvalid":
161+
validateKeys("invalid");
154162
break;
155163
case "clearInvalid":
156164
clearAllInvalid();
@@ -395,17 +403,24 @@ async function restoreAllInvalid() {
395403
});
396404
}
397405
398-
async function validateAllKeys() {
406+
async function validateKeys(status: "all" | "active" | "invalid") {
399407
if (!props.selectedGroup?.id || testingMsg) {
400408
return;
401409
}
402410
403-
testingMsg = window.$message.info("正在验证密钥...", {
411+
let statusText = "所有";
412+
if (status === "active") {
413+
statusText = "有效";
414+
} else if (status === "invalid") {
415+
statusText = "无效";
416+
}
417+
418+
testingMsg = window.$message.info(`正在验证${statusText}密钥...`, {
404419
duration: 0,
405420
});
406421
407422
try {
408-
await keysApi.validateGroupKeys(props.selectedGroup.id);
423+
await keysApi.validateGroupKeys(props.selectedGroup.id, status === "all" ? undefined : status);
409424
localStorage.removeItem("last_closed_task");
410425
appState.taskPollingTrigger++;
411426
} catch (_error) {

0 commit comments

Comments
 (0)