From e685c9c0c7d653e33eadd2a7daa1fd2587c867fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E5=BC=BA?= <357099073@qq.com> Date: Thu, 21 May 2026 18:31:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=AD=9B=E9=80=89cursor?= =?UTF-8?q?=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controllers/platform_account_pool.go | 209 +++++++++++++++++++++++++-- routers/platform/platform.go | 11 +- 2 files changed, 210 insertions(+), 10 deletions(-) diff --git a/controllers/platform_account_pool.go b/controllers/platform_account_pool.go index 5e23707..8c8563e 100644 --- a/controllers/platform_account_pool.go +++ b/controllers/platform_account_pool.go @@ -71,14 +71,14 @@ func validateCreateRow(row accountPoolCreateRow) error { if row.DataType == "tk" && row.Token == "" { return fmt.Errorf("token类型必须填写token") } - if row.DataType == "account_tk" && (row.Account == "" || row.Password == "" || row.Token == "") { - return fmt.Errorf("账号密码+token类型必须填写账号、密码、token") + if row.DataType == "account_tk" && (row.Account == "" || row.Token == "") { + return fmt.Errorf("账号密码+token类型必须填写账号和token,密码可为空") } return nil } // accountPoolListWhere 列表筛选(与各号池表字段一致) -func accountPoolListWhere(dataType, status, keyword string) (where string, args []interface{}) { +func accountPoolListWhere(dataType, status, platform, keyword, account, token, remark string) (where string, args []interface{}) { var parts []string if dataType != "" && isValidPoolType(dataType) { parts = append(parts, "data_type = ?") @@ -89,9 +89,32 @@ func accountPoolListWhere(dataType, status, keyword string) (where string, args parts = append(parts, "is_extracted = ?") args = append(args, int8(0)) case "extracted": - parts = append(parts, "is_extracted IN (?, ?)") - args = append(args, int8(1), int8(2)) + parts = append(parts, "is_extracted = ?") + args = append(args, int8(1)) + case "replenished": + parts = append(parts, "is_extracted = ?") + args = append(args, int8(2)) + case "renewed": + parts = append(parts, "is_extracted = ?") + args = append(args, int8(3)) } + if p := strings.TrimSpace(platform); p != "" { + parts = append(parts, "extracted_platform = ?") + args = append(args, p) + } + if acc := strings.TrimSpace(account); acc != "" { + parts = append(parts, "account LIKE ?") + args = append(args, "%"+acc+"%") + } + if tk := strings.TrimSpace(token); tk != "" { + parts = append(parts, "token LIKE ?") + args = append(args, "%"+tk+"%") + } + if rm := strings.TrimSpace(remark); rm != "" { + parts = append(parts, "remark LIKE ?") + args = append(args, "%"+rm+"%") + } + // 兼容旧版前端 keyword 参数:仅作为账号查询,不再合并 token/备注。 if kw := strings.TrimSpace(keyword); kw != "" { parts = append(parts, "account LIKE ?") args = append(args, "%"+kw+"%") @@ -152,10 +175,14 @@ func listPoolRows(c *beego.Controller, module string) { pageSize = 200 } keyword := strings.TrimSpace(c.GetString("keyword")) + account := strings.TrimSpace(c.GetString("account")) + token := strings.TrimSpace(c.GetString("token")) + remark := strings.TrimSpace(c.GetString("remark")) dataType := strings.TrimSpace(c.GetString("type")) status := strings.TrimSpace(c.GetString("status")) + platform := strings.TrimSpace(c.GetString("platform")) - where, whereArgs := accountPoolListWhere(dataType, status, keyword) + where, whereArgs := accountPoolListWhere(dataType, status, platform, keyword, account, token, remark) if module == "cursor" { u := strings.TrimSpace(c.GetString("usable")) if u == "1" || u == "0" { @@ -180,7 +207,7 @@ func listPoolRows(c *beego.Controller, module string) { return } sqlStr := fmt.Sprintf( - "SELECT * FROM `%s` WHERE %s ORDER BY FIELD(is_extracted, 0, 2, 1) ASC, id DESC LIMIT ? OFFSET ?", + "SELECT * FROM `%s` WHERE %s ORDER BY FIELD(is_extracted, 0, 2, 3, 1) ASC, id DESC LIMIT ? OFFSET ?", table, where, ) args := append(append([]interface{}{}, whereArgs...), pageSize, offset) @@ -202,7 +229,7 @@ func listPoolRows(c *beego.Controller, module string) { return } sqlStr := fmt.Sprintf( - "SELECT * FROM `%s` WHERE %s ORDER BY FIELD(is_extracted, 0, 2, 1) ASC, id DESC LIMIT ? OFFSET ?", + "SELECT * FROM `%s` WHERE %s ORDER BY FIELD(is_extracted, 0, 2, 3, 1) ASC, id DESC LIMIT ? OFFSET ?", table, where, ) args := append(append([]interface{}{}, whereArgs...), pageSize, offset) @@ -224,7 +251,7 @@ func listPoolRows(c *beego.Controller, module string) { return } sqlStr := fmt.Sprintf( - "SELECT * FROM `%s` WHERE %s ORDER BY FIELD(is_extracted, 0, 2, 1) ASC, id DESC LIMIT ? OFFSET ?", + "SELECT * FROM `%s` WHERE %s ORDER BY FIELD(is_extracted, 0, 2, 3, 1) ASC, id DESC LIMIT ? OFFSET ?", table, where, ) args := append(append([]interface{}{}, whereArgs...), pageSize, offset) @@ -707,6 +734,147 @@ func updatePoolRemark(c *beego.Controller, module string) { _ = c.ServeJSON() } +func validExtractPlatform(platform string) bool { + switch platform { + case "local", "xianyu", "taobao", "pinduoduo", "jingdong", "douyin", "ziyoushangcheng": + return true + default: + return false + } +} + +func updatePoolExtractFields(module string, id uint64, fields map[string]interface{}) (int64, error) { + switch module { + case "cursor": + return models.Orm.QueryTable(new(models.PlatformAccountPoolCursor)).Filter("id", id).Update(fields) + case "windsurf": + return models.Orm.QueryTable(new(models.PlatformAccountPoolWindsurf)).Filter("id", id).Update(fields) + case "krio": + return models.Orm.QueryTable(new(models.PlatformAccountPoolKiro)).Filter("id", id).Update(fields) + default: + return 0, fmt.Errorf("无效模块") + } +} + +func setPoolUnavailable(c *beego.Controller, module string) { + if _, err := requirePlatformAuth(c); err != nil { + poolJSONErr(c, 401, 401, err.Error()) + return + } + raw, err := io.ReadAll(c.Ctx.Request.Body) + if err != nil { + poolJSONErr(c, 400, 400, "参数错误") + return + } + var payload struct { + ID uint64 `json:"id"` + } + if err := json.Unmarshal(raw, &payload); err != nil || payload.ID == 0 { + poolJSONErr(c, 400, 400, "参数错误") + return + } + + now := time.Now() + fields := map[string]interface{}{ + "is_extracted": int8(1), + "extracted_time": now, + "extracted_platform": "local", + "update_time": now, + } + if module == "cursor" { + fields["is_used"] = int8(0) + } + updated, err := updatePoolExtractFields(module, payload.ID, fields) + if err != nil { + poolJSONErr(c, 500, 500, "改不可用失败: "+err.Error()) + return + } + if updated == 0 { + poolJSONErr(c, 404, 404, "记录不存在") + return + } + c.Data["json"] = map[string]interface{}{"code": 200, "msg": "已标记不可用"} + _ = c.ServeJSON() +} + +func updatePoolPlatform(c *beego.Controller, module string) { + if _, err := requirePlatformAuth(c); err != nil { + poolJSONErr(c, 401, 401, err.Error()) + return + } + raw, err := io.ReadAll(c.Ctx.Request.Body) + if err != nil { + poolJSONErr(c, 400, 400, "参数错误") + return + } + var payload struct { + ID uint64 `json:"id"` + Platform string `json:"platform"` + } + if err := json.Unmarshal(raw, &payload); err != nil || payload.ID == 0 { + poolJSONErr(c, 400, 400, "参数错误") + return + } + platform := strings.TrimSpace(payload.Platform) + if !validExtractPlatform(platform) { + poolJSONErr(c, 400, 400, "提取平台错误") + return + } + + now := time.Now() + updated, err := updatePoolExtractFields(module, payload.ID, map[string]interface{}{ + "extracted_platform": platform, + "update_time": now, + }) + if err != nil { + poolJSONErr(c, 500, 500, "平台更新失败: "+err.Error()) + return + } + if updated == 0 { + poolJSONErr(c, 404, 404, "记录不存在") + return + } + c.Data["json"] = map[string]interface{}{"code": 200, "msg": "平台更新成功"} + _ = c.ServeJSON() +} + +func unextractPoolRow(c *beego.Controller, module string) { + if _, err := requirePlatformAuth(c); err != nil { + poolJSONErr(c, 401, 401, err.Error()) + return + } + raw, err := io.ReadAll(c.Ctx.Request.Body) + if err != nil { + poolJSONErr(c, 400, 400, "参数错误") + return + } + var payload struct { + ID uint64 `json:"id"` + } + if err := json.Unmarshal(raw, &payload); err != nil || payload.ID == 0 { + poolJSONErr(c, 400, 400, "参数错误") + return + } + + now := time.Now() + updated, err := updatePoolExtractFields(module, payload.ID, map[string]interface{}{ + "is_extracted": int8(0), + "extracted_time": nil, + "extracted_platform": nil, + "update_time": now, + }) + if err != nil { + poolJSONErr(c, 500, 500, "反提取失败: "+err.Error()) + return + } + if updated == 0 { + poolJSONErr(c, 404, 404, "记录不存在") + return + } + c.Data["json"] = map[string]interface{}{"code": 200, "msg": "反提取成功"} + _ = c.ServeJSON() +} + func probePoolToken(c *beego.Controller, module string) { if _, err := requirePlatformAuth(c); err != nil { poolJSONErr(c, 401, 401, err.Error()) @@ -836,6 +1004,13 @@ func (c *PlatformAccountPoolCursorController) Replenish() { replenishPoolRow(&c. func (c *PlatformAccountPoolCursorController) UpdateRemark() { updatePoolRemark(&c.Controller, "cursor") } +func (c *PlatformAccountPoolCursorController) SetUnavailable() { + setPoolUnavailable(&c.Controller, "cursor") +} +func (c *PlatformAccountPoolCursorController) UpdatePlatform() { + updatePoolPlatform(&c.Controller, "cursor") +} +func (c *PlatformAccountPoolCursorController) Unextract() { unextractPoolRow(&c.Controller, "cursor") } func (c *PlatformAccountPoolCursorController) ProbeToken() { probePoolToken(&c.Controller, "cursor") } func (c *PlatformAccountPoolWindsurfController) List() { listPoolRows(&c.Controller, "windsurf") } @@ -851,6 +1026,15 @@ func (c *PlatformAccountPoolWindsurfController) Replenish() { func (c *PlatformAccountPoolWindsurfController) UpdateRemark() { updatePoolRemark(&c.Controller, "windsurf") } +func (c *PlatformAccountPoolWindsurfController) SetUnavailable() { + setPoolUnavailable(&c.Controller, "windsurf") +} +func (c *PlatformAccountPoolWindsurfController) UpdatePlatform() { + updatePoolPlatform(&c.Controller, "windsurf") +} +func (c *PlatformAccountPoolWindsurfController) Unextract() { + unextractPoolRow(&c.Controller, "windsurf") +} func (c *PlatformAccountPoolWindsurfController) ProbeToken() { probePoolToken(&c.Controller, "windsurf") } @@ -864,4 +1048,11 @@ func (c *PlatformAccountPoolKrioController) Replenish() { replenishPoolRow(&c.Co func (c *PlatformAccountPoolKrioController) UpdateRemark() { updatePoolRemark(&c.Controller, "krio") } +func (c *PlatformAccountPoolKrioController) SetUnavailable() { + setPoolUnavailable(&c.Controller, "krio") +} +func (c *PlatformAccountPoolKrioController) UpdatePlatform() { + updatePoolPlatform(&c.Controller, "krio") +} +func (c *PlatformAccountPoolKrioController) Unextract() { unextractPoolRow(&c.Controller, "krio") } func (c *PlatformAccountPoolKrioController) ProbeToken() { probePoolToken(&c.Controller, "krio") } diff --git a/routers/platform/platform.go b/routers/platform/platform.go index 89ceb94..85e56eb 100644 --- a/routers/platform/platform.go +++ b/routers/platform/platform.go @@ -25,7 +25,7 @@ func Register() { // 存储配置 beego.Router("/platform/storageConfig", &controllers.StorageConfigController{}, "get:GetStorageConfig") beego.Router("/platform/saveStorageConfig", &controllers.StorageConfigController{}, "post:SaveStorageConfig") - + // 存储迁移 beego.Router("/platform/storage/migrateToQiniu", &controllers.StorageMigrationController{}, "post:MigrateToQiniu") beego.Router("/platform/storage/migrationProgress", &controllers.StorageMigrationController{}, "get:GetMigrationProgress") @@ -169,6 +169,9 @@ func Register() { beego.Router("/platform/accountPool/cursor/detail/:id", &controllers.PlatformAccountPoolCursorController{}, "get:Detail") beego.Router("/platform/accountPool/cursor/extract", &controllers.PlatformAccountPoolCursorController{}, "post:Extract") beego.Router("/platform/accountPool/cursor/updateRemark", &controllers.PlatformAccountPoolCursorController{}, "post:UpdateRemark") + beego.Router("/platform/accountPool/cursor/setUnavailable", &controllers.PlatformAccountPoolCursorController{}, "post:SetUnavailable") + beego.Router("/platform/accountPool/cursor/updatePlatform", &controllers.PlatformAccountPoolCursorController{}, "post:UpdatePlatform") + beego.Router("/platform/accountPool/cursor/unextract", &controllers.PlatformAccountPoolCursorController{}, "post:Unextract") beego.Router("/platform/accountPool/cursor/replenish", &controllers.PlatformAccountPoolCursorController{}, "post:Replenish") beego.Router("/platform/accountPool/cursor/probeToken", &controllers.PlatformAccountPoolCursorController{}, "post:ProbeToken") @@ -178,6 +181,9 @@ func Register() { beego.Router("/platform/accountPool/windsurf/detail/:id", &controllers.PlatformAccountPoolWindsurfController{}, "get:Detail") beego.Router("/platform/accountPool/windsurf/extract", &controllers.PlatformAccountPoolWindsurfController{}, "post:Extract") beego.Router("/platform/accountPool/windsurf/updateRemark", &controllers.PlatformAccountPoolWindsurfController{}, "post:UpdateRemark") + beego.Router("/platform/accountPool/windsurf/setUnavailable", &controllers.PlatformAccountPoolWindsurfController{}, "post:SetUnavailable") + beego.Router("/platform/accountPool/windsurf/updatePlatform", &controllers.PlatformAccountPoolWindsurfController{}, "post:UpdatePlatform") + beego.Router("/platform/accountPool/windsurf/unextract", &controllers.PlatformAccountPoolWindsurfController{}, "post:Unextract") beego.Router("/platform/accountPool/windsurf/replenish", &controllers.PlatformAccountPoolWindsurfController{}, "post:Replenish") beego.Router("/platform/accountPool/windsurf/probeToken", &controllers.PlatformAccountPoolWindsurfController{}, "post:ProbeToken") @@ -187,6 +193,9 @@ func Register() { beego.Router("/platform/accountPool/krio/detail/:id", &controllers.PlatformAccountPoolKrioController{}, "get:Detail") beego.Router("/platform/accountPool/krio/extract", &controllers.PlatformAccountPoolKrioController{}, "post:Extract") beego.Router("/platform/accountPool/krio/updateRemark", &controllers.PlatformAccountPoolKrioController{}, "post:UpdateRemark") + beego.Router("/platform/accountPool/krio/setUnavailable", &controllers.PlatformAccountPoolKrioController{}, "post:SetUnavailable") + beego.Router("/platform/accountPool/krio/updatePlatform", &controllers.PlatformAccountPoolKrioController{}, "post:UpdatePlatform") + beego.Router("/platform/accountPool/krio/unextract", &controllers.PlatformAccountPoolKrioController{}, "post:Unextract") beego.Router("/platform/accountPool/krio/replenish", &controllers.PlatformAccountPoolKrioController{}, "post:Replenish") beego.Router("/platform/accountPool/krio/probeToken", &controllers.PlatformAccountPoolKrioController{}, "post:ProbeToken") }