Files
zzyxyz_go_api/internal/bookmarks/bookmark.go
zzy b2cc27b8f5 refactor(bookmark): 重构 bookmark 服务生成配置和内部引用
将 bookmark 和 user_np 服务的生成配置分离为 server 和 client 包,
并更新了相应的导入路径。同时更新了 OpenAPI 配置文件中的包名、输出路径及
启用 strict-server 模式以增强类型安全。

此外,同步更新了 VFS 服务的客户端和服务端生成配置,并完善了其 OpenAPI
错误响应定义与二进制内容支持,增强了 API 的规范性和健壮性。

修复了部分权限校验逻辑,并调整了中间件注册方式以适配新的严格模式接口。
2025-09-25 16:15:34 +08:00

240 lines
5.7 KiB
Go
Raw 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.

// internal/handlers/note_link.go
package bookmarks
import (
"net/http"
api "git.zzyxyz.com/zzy/zzyxyz_go_api/gen/bookmarks_server"
"git.zzyxyz.com/zzy/zzyxyz_go_api/internal/bookmarks/models"
"github.com/gin-gonic/gin"
_ "github.com/mattn/go-sqlite3"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type BookMarksImpl struct {
db *gorm.DB
}
var adminToken *string
func validateApiKey(apiKey string) bool {
if adminToken != nil && apiKey == *adminToken {
return true
}
return false
}
func AuthMiddleware() api.MiddlewareFunc {
return func(c *gin.Context) {
// 检查当前请求是否需要认证
if _, exists := c.Get(api.ApiKeyAuthScopes); exists {
// 提取 API Key
apiKey := c.GetHeader("X-BookMark-Token")
// 验证 API Key您需要实现这个逻辑
if apiKey == "" || !validateApiKey(apiKey) {
c.JSON(http.StatusUnauthorized, api.Error{
Errtype: "Unauthorized",
Message: "Invalid or missing API key",
})
c.Abort()
return
}
}
c.Next()
}
}
func NewBookMarkPermission() (*api.GinServerOptions, error) {
return &api.GinServerOptions{
Middlewares: []api.MiddlewareFunc{AuthMiddleware()},
}, nil
}
func NewBookMarks(dbPath string) (*BookMarksImpl, error) {
var err error
var db *gorm.DB
db, err = gorm.Open(sqlite.Open(dbPath), &gorm.Config{})
if err != nil {
return nil, err
}
// 自动迁移表结构
err = db.AutoMigrate(&models.Bookmark{})
if err != nil {
return nil, err
}
return &BookMarksImpl{db: db}, nil
}
func (b *BookMarksImpl) FindBMFromExternalID(externalID int64) (models.Bookmark, error) {
var db = b.db
var bookmark models.Bookmark
// 使用ExternalID查询书签
if err := db.Where("external_id = ?", externalID).First(&bookmark).Error; err != nil {
return bookmark, err
}
return bookmark, nil
}
// CreateBookmark implements api.ServerInterface.
func (b *BookMarksImpl) CreateBookmark(c *gin.Context, id int64) {
var db = b.db
var req api.BookmarkRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, api.Error{
Errtype: "ParameterError",
Message: "Invalid request parameters",
})
return
}
// 检查外部ID是否已经存在
var existingBookmark models.Bookmark
result := db.Where("external_id = ?", id).First(&existingBookmark)
if result.Error == nil {
// ExternalID已存在返回冲突错误
c.JSON(http.StatusConflict, api.Error{
Errtype: "ConflictError",
Message: "Bookmark with this External ID already exists",
})
return
} else if result.Error != gorm.ErrRecordNotFound {
// 数据库查询出错
c.JSON(http.StatusInternalServerError, api.Error{
Errtype: "DatabaseError",
Message: "Database query error",
})
return
}
bookmark := bookmarkReq2Model(req)
bookmark.ExternalID = id // 设置外部ID
if err := db.Create(&bookmark).Error; err != nil {
c.JSON(http.StatusInternalServerError, api.Error{
Errtype: "DatabaseError",
Message: "Failed to create bookmark",
})
return
}
response := bookmarkModel2Res(bookmark)
c.JSON(http.StatusCreated, response)
}
// DeleteBookmark implements api.ServerInterface.
func (b *BookMarksImpl) DeleteBookmark(c *gin.Context, id int64) {
var db = b.db
var bookmark models.Bookmark
// 使用ExternalID删除书签
if err := db.Where("external_id = ?", id).Delete(&bookmark).Error; err != nil {
c.JSON(http.StatusInternalServerError, api.Error{
Errtype: "DatabaseError",
Message: "Failed to delete bookmark",
})
return
}
c.Status(http.StatusNoContent)
}
// GetBookmark implements api.ServerInterface.
func (b *BookMarksImpl) GetBookmark(c *gin.Context, id int64) {
var db = b.db
var bookmark models.Bookmark
// 使用ExternalID查询书签
if err := db.Where("external_id = ?", id).First(&bookmark).Error; err != nil {
c.JSON(http.StatusNotFound, api.Error{
Errtype: "NotFoundError",
Message: "Bookmark not found",
})
return
}
// 构造响应
response := bookmarkModel2Res(bookmark)
c.JSON(http.StatusOK, response)
}
// UpdateBookmark implements api.ServerInterface.
func (b *BookMarksImpl) UpdateBookmark(c *gin.Context, id int64) {
var db = b.db
var req api.BookmarkRequest
// 绑定请求参数
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, api.Error{
Errtype: "ParameterError",
Message: "Invalid request parameters",
})
return
}
// 查找要更新的书签使用ExternalID
var bookmark models.Bookmark
if err := db.Where("external_id = ?", id).First(&bookmark).Error; err != nil {
c.JSON(http.StatusNotFound, api.Error{
Errtype: "NotFoundError",
Message: "Bookmark not found",
})
return
}
// 更新书签字段
if req.Name != "" {
bookmark.Name = req.Name
}
if req.Link != nil {
bookmark.Link = req.Link
}
if req.Detail != nil {
bookmark.Detail = req.Detail
}
if req.Description != nil {
bookmark.Description = req.Description
}
// 保存更新
if err := db.Save(&bookmark).Error; err != nil {
c.JSON(http.StatusInternalServerError, api.Error{
Errtype: "DatabaseError",
Message: "Failed to update bookmark",
})
return
}
// 构造响应
response := bookmarkModel2Res(bookmark)
c.JSON(http.StatusOK, response)
}
func bookmarkReq2Model(req api.BookmarkRequest) models.Bookmark {
return models.Bookmark{
Name: req.Name,
Link: req.Link,
Detail: req.Detail,
Description: req.Description,
}
}
func bookmarkModel2Res(bookmark models.Bookmark) api.BookmarkResponse {
return api.BookmarkResponse{
Id: bookmark.ID,
Name: bookmark.Name,
Link: bookmark.Link,
Detail: bookmark.Detail,
Description: bookmark.Description,
CreatedAt: bookmark.CreatedAt,
}
}
// Make sure we conform to ServerInterface
var _ api.ServerInterface = (*BookMarksImpl)(nil)