yunzerwebsiteallinone/go/controllers/api_cursor_detect.go
2026-06-17 00:44:33 +08:00

155 lines
4.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package controllers
import (
"fmt"
"strconv"
"strings"
"time"
"server/models"
"github.com/beego/beego/v2/client/orm"
beego "github.com/beego/beego/v2/server/web"
)
// ApiCursorDetectController Cursor Token 顺序读取接口(不改变号池状态)
//
// 用途:
// - 前端传入 start_id/current_id/id直接读取该 ID 对应的 Cursor Token。
// - 只读取记录,不更新 is_extracted、extracted_time、extracted_platform、is_used 等任何状态。
// - 不再跳过已提取的记录,输入什么 ID 就提取什么 ID。
// - 返回 next_id前端下一次点击时传 next_id即可实现 11 -> 12 -> 13 递增读取。
//
// 示例:
//
// GET /api/cursor/token/peek?id=11
// GET /api/cursor/token/peek?start_id=11
// GET /api/cursor/token/peek?current_id=11
//
// 可选参数:
// - data_type=tk/account/account_tk默认 tk
type ApiCursorDetectController struct {
beego.Controller
}
func (c *ApiCursorDetectController) cursorDetectJSONErr(httpStatus, code int, msg string) {
c.Ctx.Output.SetStatus(httpStatus)
c.Data["json"] = map[string]interface{}{
"code": code,
"msg": msg,
}
_ = c.ServeJSON()
}
func (c *ApiCursorDetectController) setTokenUsableByID(isUsed int8) {
id, err := c.readStartID()
if err != nil {
c.cursorDetectJSONErr(400, 400, err.Error())
return
}
now := time.Now()
updated, err := models.Orm.QueryTable(new(models.PlatformAccountPoolCursor)).
Filter("id", id).
Filter("delete_time__isnull", true).
Update(orm.Params{
"is_used": isUsed,
"update_time": now,
})
if err != nil {
c.cursorDetectJSONErr(500, 500, "更新失败: "+err.Error())
return
}
if updated == 0 {
c.cursorDetectJSONErr(404, 404, "当前 ID 数据不存在或已删除")
return
}
c.Data["json"] = map[string]interface{}{
"code": 200,
"msg": "success",
"data": map[string]interface{}{
"id": id,
"is_used": isUsed,
"is_available": isUsed == 1,
"state_changed": true,
"update_time": now,
},
}
_ = c.ServeJSON()
}
// MarkTokenAvailable 将当前 ID 的 Cursor Token 标记为可用。
func (c *ApiCursorDetectController) MarkTokenAvailable() {
c.setTokenUsableByID(1)
}
// MarkTokenUnavailable 将当前 ID 的 Cursor Token 标记为不可用/用完。
func (c *ApiCursorDetectController) MarkTokenUnavailable() {
c.setTokenUsableByID(0)
}
// PeekToken 按 ID 顺序读取 Cursor Token不改变任何状态。
func (c *ApiCursorDetectController) PeekToken() {
startID, err := c.readStartID()
if err != nil {
c.cursorDetectJSONErr(400, 400, err.Error())
return
}
var row models.PlatformAccountPoolCursor
qs := models.Orm.QueryTable(new(models.PlatformAccountPoolCursor)).
Filter("id", startID).
Filter("delete_time__isnull", true).
Exclude("token", "")
err = qs.One(&row)
if err != nil {
if err == orm.ErrNoRows {
c.cursorDetectJSONErr(404, 404, "指定 ID 的 Cursor Token 不存在或已删除")
return
}
c.cursorDetectJSONErr(500, 500, "查询失败: "+err.Error())
return
}
c.Data["json"] = map[string]interface{}{
"code": 200,
"msg": "success",
"data": map[string]interface{}{
"id": row.ID,
"next_id": row.ID + 1,
"data_type": row.DataType,
"account": row.Account,
"password": row.Password,
"token": row.Token,
"remark": row.Remark,
"is_used": row.IsUsed,
"create_time": row.CreateTime,
// 明确告诉前端:本接口只是读取,没有更新号池状态。
"state_changed": false,
},
}
_ = c.ServeJSON()
}
func (c *ApiCursorDetectController) readStartID() (uint64, error) {
raw := strings.TrimSpace(c.GetString("id"))
if raw == "" {
raw = strings.TrimSpace(c.GetString("start_id"))
}
if raw == "" {
raw = strings.TrimSpace(c.GetString("current_id"))
}
if raw == "" {
return 0, fmt.Errorf("缺少参数 id/start_id/current_id")
}
id, err := strconv.ParseUint(raw, 10, 64)
if err != nil || id == 0 {
return 0, fmt.Errorf("id 必须是大于 0 的整数")
}
return id, nil
}