@@ -1102,10 +1102,26 @@ func (h *Handler) getAccountUsageWindows(ctx context.Context) (map[int64]*databa
11021102type addAccountReq struct {
11031103 Name string `json:"name"`
11041104 RefreshToken string `json:"refresh_token"`
1105+ SessionToken string `json:"session_token"`
11051106 ProxyURL string `json:"proxy_url"`
11061107}
11071108
1108- // AddAccount 添加新账号(支持批量:refresh_token 按行分割)
1109+ func splitAccountCredentialLines (raw string , sanitize bool ) []string {
1110+ lines := strings .Split (raw , "\n " )
1111+ tokens := make ([]string , 0 , len (lines ))
1112+ for _ , line := range lines {
1113+ token := strings .TrimSpace (line )
1114+ if sanitize {
1115+ token = strings .TrimSpace (security .SanitizeInput (token ))
1116+ }
1117+ if token != "" {
1118+ tokens = append (tokens , token )
1119+ }
1120+ }
1121+ return tokens
1122+ }
1123+
1124+ // AddAccount 添加新账号(支持批量:refresh_token/session_token 按行分割)
11091125func (h * Handler ) AddAccount (c * gin.Context ) {
11101126 var req addAccountReq
11111127 if err := c .ShouldBindJSON (& req ); err != nil {
@@ -1117,8 +1133,8 @@ func (h *Handler) AddAccount(c *gin.Context) {
11171133 req .Name = security .SanitizeInput (req .Name )
11181134 req .ProxyURL = security .SanitizeInput (req .ProxyURL )
11191135
1120- if req .RefreshToken == "" {
1121- writeError (c , http .StatusBadRequest , "refresh_token 是必填字段" )
1136+ if strings . TrimSpace ( req .RefreshToken ) == "" && strings . TrimSpace ( req . SessionToken ) == "" {
1137+ writeError (c , http .StatusBadRequest , "refresh_token 或 session_token 是必填字段" )
11221138 return
11231139 }
11241140
@@ -1140,23 +1156,40 @@ func (h *Handler) AddAccount(c *gin.Context) {
11401156 return
11411157 }
11421158
1143- // 按行分割,支持批量添加
1144- lines := strings .Split (req .RefreshToken , "\n " )
1145- var tokens []string
1146- for _ , line := range lines {
1147- t := strings .TrimSpace (security .SanitizeInput (line ))
1148- if t != "" {
1149- tokens = append (tokens , t )
1159+ // 按行分割,支持批量添加。refresh_token 与 session_token 同时填写时,
1160+ // session_token 可填写一行应用到所有 RT,也可与 RT 行数一一对应。
1161+ refreshTokens := splitAccountCredentialLines (req .RefreshToken , true )
1162+ sessionTokens := splitAccountCredentialLines (req .SessionToken , true )
1163+ total := len (refreshTokens )
1164+ if total == 0 {
1165+ total = len (sessionTokens )
1166+ }
1167+ if len (refreshTokens ) > 0 && len (sessionTokens ) > 1 && len (sessionTokens ) != len (refreshTokens ) {
1168+ writeError (c , http .StatusBadRequest , "session_token 行数需为 1 或与 refresh_token 行数一致" )
1169+ return
1170+ }
1171+
1172+ var seeds []tokenCredentialSeed
1173+ for i := 0 ; i < total ; i ++ {
1174+ seed := tokenCredentialSeed {}
1175+ if len (refreshTokens ) > 0 {
1176+ seed .refreshToken = refreshTokens [i ]
1177+ }
1178+ if len (sessionTokens ) == 1 {
1179+ seed .sessionToken = sessionTokens [0 ]
1180+ } else if len (sessionTokens ) > 1 {
1181+ seed .sessionToken = sessionTokens [i ]
11501182 }
1183+ seeds = append (seeds , seed )
11511184 }
11521185
1153- if len (tokens ) == 0 {
1154- writeError (c , http .StatusBadRequest , "未找到有效的 Refresh Token" )
1186+ if len (seeds ) == 0 {
1187+ writeError (c , http .StatusBadRequest , "未找到有效的 Refresh Token 或 Session Token " )
11551188 return
11561189 }
11571190
11581191 // 限制批量添加数量
1159- if len (tokens ) > 100 {
1192+ if len (seeds ) > 100 {
11601193 writeError (c , http .StatusBadRequest , "单次最多添加100个账号" )
11611194 return
11621195 }
@@ -1167,15 +1200,15 @@ func (h *Handler) AddAccount(c *gin.Context) {
11671200 successCount := 0
11681201 failCount := 0
11691202
1170- for i , rt := range tokens {
1203+ for i , seed := range seeds {
11711204 name := req .Name
11721205 if name == "" {
11731206 name = fmt .Sprintf ("account-%d" , i + 1 )
1174- } else if len (tokens ) > 1 {
1207+ } else if len (seeds ) > 1 {
11751208 name = fmt .Sprintf ("%s-%d" , req .Name , i + 1 )
11761209 }
11771210
1178- id , err := h .db .InsertAccount (ctx , name , rt , req .ProxyURL )
1211+ id , err := h .db .InsertAccountWithCredentials (ctx , name , tokenCredentialMap ( seed ) , req .ProxyURL )
11791212 if err != nil {
11801213 log .Printf ("批量添加账号 %d 失败: %v" , i + 1 , err )
11811214 failCount ++
@@ -1186,11 +1219,7 @@ func (h *Handler) AddAccount(c *gin.Context) {
11861219 h .db .InsertAccountEventAsync (id , "added" , "manual" )
11871220
11881221 // 热加载:直接加入内存池
1189- newAcc := & auth.Account {
1190- DBID : id ,
1191- RefreshToken : rt ,
1192- ProxyURL : req .ProxyURL ,
1193- }
1222+ newAcc := accountFromCredentialSeed (id , req .ProxyURL , seed )
11941223 h .store .AddAccount (newAcc )
11951224
11961225 if ! h .store .GetLazyMode () {
0 commit comments