235 lines
5.7 KiB
Go
235 lines
5.7 KiB
Go
package handlers
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"time"
|
|
|
|
"go.mongodb.org/mongo-driver/v2/bson"
|
|
"go.mongodb.org/mongo-driver/v2/mongo"
|
|
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
|
|
|
"yh_web/server/config"
|
|
"yh_web/server/models"
|
|
"yh_web/server/utils"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func GetUsers(c *gin.Context) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer cancel()
|
|
|
|
coll := config.GetDB(config.DBName).Collection("users")
|
|
|
|
page := 1
|
|
pageSize := 20
|
|
if p := c.Query("page"); p != "" {
|
|
if v, err := parseInt(p); err == nil && v > 0 {
|
|
page = v
|
|
}
|
|
}
|
|
if ps := c.Query("page_size"); ps != "" {
|
|
if v, err := parseInt(ps); err == nil && v > 0 && v <= 100 {
|
|
pageSize = v
|
|
}
|
|
}
|
|
|
|
skip := (page - 1) * pageSize
|
|
opts := options.Find().SetSkip(int64(skip)).SetLimit(int64(pageSize)).SetSort(bson.D{{Key: "_id", Value: -1}})
|
|
|
|
cursor, err := coll.Find(ctx, bson.M{}, opts)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
defer cursor.Close(ctx)
|
|
|
|
var users []models.User
|
|
if err = cursor.All(ctx, &users); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
total, _ := coll.CountDocuments(ctx, bson.M{})
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"list": users,
|
|
"total": total,
|
|
"page": page,
|
|
"page_size": pageSize,
|
|
})
|
|
}
|
|
|
|
func GetUserByID(c *gin.Context) {
|
|
id := c.Param("id")
|
|
oid, err := bson.ObjectIDFromHex(id)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的 ID"})
|
|
return
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
var user models.User
|
|
err = config.GetDB(config.DBName).Collection("users").FindOne(ctx, bson.M{"_id": oid}).Decode(&user)
|
|
if err != nil {
|
|
if errors.Is(err, mongo.ErrNoDocuments) {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, user)
|
|
}
|
|
|
|
func CreateUser(c *gin.Context) {
|
|
var input models.UserCreateInput
|
|
if err := c.ShouldBindJSON(&input); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
coll := config.GetDB(config.DBName).Collection("users")
|
|
|
|
// 检查用户名是否已存在
|
|
var exist models.User
|
|
if err := coll.FindOne(ctx, bson.M{"username": input.Username}).Decode(&exist); err == nil {
|
|
c.JSON(http.StatusConflict, gin.H{"error": "用户名已存在"})
|
|
return
|
|
}
|
|
if err := coll.FindOne(ctx, bson.M{"email": input.Email}).Decode(&exist); err == nil {
|
|
c.JSON(http.StatusConflict, gin.H{"error": "邮箱已存在"})
|
|
return
|
|
}
|
|
|
|
if input.Role == "" {
|
|
input.Role = "user"
|
|
}
|
|
roleID := input.RoleID
|
|
if roleID == 0 {
|
|
roleID = models.RoleIDUser
|
|
}
|
|
|
|
doc := bson.M{
|
|
"username": input.Username,
|
|
"email": input.Email,
|
|
"password": utils.HashPassword(input.Password),
|
|
"role": input.Role,
|
|
"role_id": roleID,
|
|
"is_beta": input.IsBeta,
|
|
}
|
|
if input.TrialStartDate != "" {
|
|
doc["trial_start_date"] = input.TrialStartDate
|
|
}
|
|
if input.TrialEndDate != "" {
|
|
doc["trial_end_date"] = input.TrialEndDate
|
|
}
|
|
if input.LLM != "" {
|
|
doc["llm"] = input.LLM
|
|
}
|
|
|
|
res, err := coll.InsertOne(ctx, doc)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusCreated, gin.H{"id": res.InsertedID, "message": "创建成功"})
|
|
}
|
|
|
|
func UpdateUser(c *gin.Context) {
|
|
id := c.Param("id")
|
|
oid, err := bson.ObjectIDFromHex(id)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的 ID"})
|
|
return
|
|
}
|
|
|
|
var input models.UserUpdateInput
|
|
if err := c.ShouldBindJSON(&input); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
update := bson.M{}
|
|
if input.Username != nil {
|
|
update["username"] = *input.Username
|
|
}
|
|
if input.Email != nil {
|
|
update["email"] = *input.Email
|
|
}
|
|
if input.Password != nil && *input.Password != "" {
|
|
update["password"] = utils.HashPassword(*input.Password)
|
|
}
|
|
if input.Role != nil {
|
|
update["role"] = *input.Role
|
|
}
|
|
if input.IsBeta != nil {
|
|
update["is_beta"] = *input.IsBeta
|
|
}
|
|
if input.TrialStartDate != nil {
|
|
update["trial_start_date"] = *input.TrialStartDate
|
|
}
|
|
if input.TrialEndDate != nil {
|
|
update["trial_end_date"] = *input.TrialEndDate
|
|
}
|
|
if input.LLM != nil {
|
|
update["llm"] = *input.LLM
|
|
}
|
|
if input.RoleID != nil {
|
|
update["role_id"] = *input.RoleID
|
|
}
|
|
|
|
if len(update) == 0 {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "无有效更新字段"})
|
|
return
|
|
}
|
|
|
|
res, err := config.GetDB(config.DBName).Collection("users").UpdateOne(ctx, bson.M{"_id": oid}, bson.M{"$set": update})
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
if res.MatchedCount == 0 {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "更新成功"})
|
|
}
|
|
|
|
func DeleteUser(c *gin.Context) {
|
|
id := c.Param("id")
|
|
oid, err := bson.ObjectIDFromHex(id)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的 ID"})
|
|
return
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
res, err := config.GetDB(config.DBName).Collection("users").DeleteOne(ctx, bson.M{"_id": oid})
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
if res.DeletedCount == 0 {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "删除成功"})
|
|
}
|