feat(admin): 添加用户管理和Linux.do登录功能

- 新增AdminUser类型定义及用户管理API接口
- 实现用户列表查询、保存和删除功能
- 添加Linux.do第三方登录支持
- 集成Linux.do OAuth认证流程
- 在系统设置中添加Linux.do登录配置选项
- 实现算力点余额调整记录功能
- 优化搜索组件关键词状态管理
- 更新数据库迁移添加credit_logs表
- 完善用户状态和信用等级验证逻辑
This commit is contained in:
HouYunFei
2026-05-25 11:21:09 +08:00
parent f871a5d015
commit b2cae2471d
25 changed files with 1023 additions and 117 deletions
+50 -10
View File
@@ -3,6 +3,8 @@ package handler
import (
"encoding/json"
"net/http"
"net/url"
"strings"
"github.com/basketikun/infinite-canvas/model"
"github.com/basketikun/infinite-canvas/service"
@@ -19,10 +21,15 @@ type registerRequest struct {
}
type saveUserRequest struct {
ID string `json:"id"`
Username string `json:"username"`
Password string `json:"password"`
Role model.UserRole `json:"role"`
ID string `json:"id"`
Username string `json:"username"`
Password string `json:"password"`
Email string `json:"email"`
DisplayName string `json:"displayName"`
AvatarURL string `json:"avatarUrl"`
Role model.UserRole `json:"role"`
Credits int `json:"credits"`
Status model.UserStatus `json:"status"`
}
func Register(w http.ResponseWriter, r *http.Request) {
@@ -44,11 +51,25 @@ func Login(w http.ResponseWriter, r *http.Request) {
FailError(w, err)
return
}
if session.User.Role != model.UserRoleAdmin {
Fail(w, "需要管理员权限")
OK(w, session)
}
func LinuxDoAuthorize(w http.ResponseWriter, r *http.Request) {
authURL, err := service.LinuxDoAuthorizeURL(r.URL.Query().Get("redirect"))
if err != nil {
FailError(w, err)
return
}
OK(w, session)
http.Redirect(w, r, authURL, http.StatusFound)
}
func LinuxDoCallback(w http.ResponseWriter, r *http.Request) {
session, redirect, err := service.LoginWithLinuxDo(r.URL.Query().Get("code"), r.URL.Query().Get("state"))
if err != nil {
http.Redirect(w, r, loginRedirect(redirect, "", err.Error()), http.StatusFound)
return
}
http.Redirect(w, r, loginRedirect(redirect, session.Token, ""), http.StatusFound)
}
func AdminLogin(w http.ResponseWriter, r *http.Request) {
@@ -87,9 +108,14 @@ func AdminSaveUser(w http.ResponseWriter, r *http.Request) {
var request saveUserRequest
_ = json.NewDecoder(r.Body).Decode(&request)
user, err := service.SaveUser(model.User{
ID: request.ID,
Username: request.Username,
Role: request.Role,
ID: request.ID,
Username: request.Username,
Email: request.Email,
DisplayName: request.DisplayName,
AvatarURL: request.AvatarURL,
Role: request.Role,
Credits: request.Credits,
Status: request.Status,
}, request.Password)
if err != nil {
FailError(w, err)
@@ -98,6 +124,20 @@ func AdminSaveUser(w http.ResponseWriter, r *http.Request) {
OK(w, user)
}
func loginRedirect(redirect string, token string, message string) string {
values := url.Values{}
if strings.TrimSpace(token) != "" {
values.Set("token", token)
}
if strings.TrimSpace(message) != "" {
values.Set("error", message)
}
if strings.TrimSpace(redirect) != "" {
values.Set("redirect", redirect)
}
return "/login?" + values.Encode()
}
func AdminDeleteUser(w http.ResponseWriter, r *http.Request, id string) {
if err := service.DeleteUser(id); err != nil {
FailError(w, err)