feat(bookmark): 初始化书签服务并配置路由与权限控制
新增书签服务主程序,使用 Gin 框架搭建 HTTP 服务器,并注册书签相关接口处理器。 配置 CORS 中间件以支持跨域请求。服务监听端口为 8081。 feat(user_np): 初始化用户权限服务并注册认证接口 新增用户权限服务主程序,使用 Gin 框架搭建 HTTP 服务器,并注册登录、注册及修改密码等接口处理器。 服务监听端口为 8082。 refactor(config): 重构 OpenAPI 配置文件结构并拆分模块 将原有合并的 OpenAPI 配置文件按功能模块拆分为 bookmark 和 user_np 两个独立目录, 分别管理各自的 server、client 及 API 定义文件,便于后续维护和扩展。 refactor(vfs): 调整虚拟文件系统 API 接口路径与参数定义 更新 VFS API 配置文件,修改部分接口路径及参数结构, 如将文件路径参数由 path 转为 query 参数,并优化响应结构体定义。
This commit is contained in:
@ -3,16 +3,10 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
api "git.zzyxyz.com/zzy/zzyxyz_go_api/gen/bookmarks"
|
||||
"git.zzyxyz.com/zzy/zzyxyz_go_api/internal/models"
|
||||
"github.com/casbin/casbin/v2"
|
||||
"github.com/gin-gonic/gin"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"gorm.io/driver/sqlite"
|
||||
@ -23,27 +17,9 @@ type BookMarksImpl struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
// GetFolderMounts implements api.ServerInterface.
|
||||
func (b *BookMarksImpl) GetFolderMounts(c *gin.Context, id int64) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// MountFolder implements api.ServerInterface.
|
||||
func (b *BookMarksImpl) MountFolder(c *gin.Context, id int64) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// UnmountFolder implements api.ServerInterface.
|
||||
func (b *BookMarksImpl) UnmountFolder(c *gin.Context, id int64) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
const forlder_root_id = 1
|
||||
|
||||
var enforcer *casbin.Enforcer
|
||||
var adminToken *string
|
||||
|
||||
func validateApiKey(url *url.URL, apiKey string) bool {
|
||||
func validateApiKey(apiKey string) bool {
|
||||
if adminToken != nil && apiKey == *adminToken {
|
||||
return true
|
||||
}
|
||||
@ -58,8 +34,9 @@ func AuthMiddleware() api.MiddlewareFunc {
|
||||
// 提取 API Key
|
||||
apiKey := c.GetHeader("X-BookMark-Token")
|
||||
|
||||
return
|
||||
// 验证 API Key(您需要实现这个逻辑)
|
||||
if apiKey == "" || !validateApiKey(c.Request.URL, apiKey) {
|
||||
if apiKey == "" || !validateApiKey(apiKey) {
|
||||
c.JSON(http.StatusUnauthorized, api.Error{
|
||||
Errtype: "Unauthorized",
|
||||
Message: "Invalid or missing API key",
|
||||
@ -73,56 +50,17 @@ func AuthMiddleware() api.MiddlewareFunc {
|
||||
}
|
||||
|
||||
func NewBookMarkPermission() (*api.GinServerOptions, error) {
|
||||
// 一行代码生成安全的随机token
|
||||
token := make([]byte, 16)
|
||||
rand.Read(token) // 忽略错误处理以简化代码(生产环境建议处理)
|
||||
tokenStr := hex.EncodeToString(token)
|
||||
adminToken = &tokenStr
|
||||
log.Printf("Admin API Token (for Swagger testing): %s", *adminToken)
|
||||
|
||||
if e, err := casbin.NewEnforcer("./config/model.conf", ".data/policy.csv"); err == nil {
|
||||
log.Fatalf("Failed to create casbin enforcer: %v", err)
|
||||
} else {
|
||||
enforcer = e
|
||||
}
|
||||
|
||||
return &api.GinServerOptions{
|
||||
Middlewares: []api.MiddlewareFunc{AuthMiddleware()},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *BookMarksImpl) GetFolderDefaultRoot(folderID *int64) (*models.Folder, error) {
|
||||
var db *gorm.DB = b.db
|
||||
var real_root_id int64 = forlder_root_id
|
||||
|
||||
// 设置默认父文件夹ID为根目录
|
||||
parentID := real_root_id
|
||||
if folderID != nil && *folderID != 0 {
|
||||
parentID = *folderID
|
||||
}
|
||||
|
||||
// 检查文件夹是否存在(Find 不会在找不到记录时返回错误)
|
||||
var parentFolder models.Folder
|
||||
result := db.Limit(1).Find(&parentFolder, parentID)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
// 检查是否找到了记录
|
||||
if result.RowsAffected == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return &parentFolder, nil
|
||||
}
|
||||
|
||||
func bookmarkReq2Model(req api.BookmarkRequest, parentID int64) models.Bookmark {
|
||||
func bookmarkReq2Model(req api.BookmarkRequest) models.Bookmark {
|
||||
return models.Bookmark{
|
||||
Name: req.Name,
|
||||
Link: req.Link,
|
||||
Detail: req.Detail,
|
||||
Description: req.Description,
|
||||
ParentID: parentID,
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,28 +71,10 @@ func bookmarkModel2Res(bookmark models.Bookmark) api.BookmarkResponse {
|
||||
Link: bookmark.Link,
|
||||
Detail: bookmark.Detail,
|
||||
Description: bookmark.Description,
|
||||
ParentId: bookmark.ParentID,
|
||||
CreatedAt: bookmark.CreatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
func folderReq2Model(req api.FolderRequest, parentID *int64) models.Folder {
|
||||
return models.Folder{
|
||||
Name: req.Name,
|
||||
ParentID: parentID,
|
||||
}
|
||||
}
|
||||
|
||||
func folderModel2Res(folder models.Folder) api.FolderResponse {
|
||||
return api.FolderResponse{
|
||||
Id: folder.ID,
|
||||
Name: folder.Name,
|
||||
ParentId: folder.ParentID,
|
||||
CreatedAt: folder.CreatedAt,
|
||||
UpdatedAt: folder.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
func NewBookMarks(dbPath string) (*BookMarksImpl, error) {
|
||||
var err error
|
||||
var db *gorm.DB
|
||||
@ -164,35 +84,27 @@ func NewBookMarks(dbPath string) (*BookMarksImpl, error) {
|
||||
}
|
||||
|
||||
// 自动迁移表结构
|
||||
err = db.AutoMigrate(&models.Folder{}, &models.Bookmark{})
|
||||
err = db.AutoMigrate(&models.Bookmark{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 创建根文件夹(如果不存在)
|
||||
var rootFolder models.Folder
|
||||
result := db.Limit(1).Find(&rootFolder, forlder_root_id)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
if result.RowsAffected == 0 {
|
||||
// 根文件夹不存在,创建它
|
||||
rootFolder = models.Folder{
|
||||
ID: forlder_root_id,
|
||||
Name: "Root",
|
||||
ParentID: nil, // 根目录指向NULL
|
||||
}
|
||||
if err := db.Create(&rootFolder).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to create root folder: %w", 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) {
|
||||
func (b *BookMarksImpl) CreateBookmark(c *gin.Context, id int64) {
|
||||
var db = b.db
|
||||
var req api.BookmarkRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@ -203,19 +115,27 @@ func (b *BookMarksImpl) CreateBookmark(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
var parentID int64
|
||||
if folder, err := b.GetFolderDefaultRoot(req.ParentId); err != nil || folder == nil {
|
||||
c.JSON(http.StatusNotFound, api.Error{
|
||||
Errtype: "NotFoundError",
|
||||
Message: "Parent folder not found",
|
||||
// 检查外部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
|
||||
} else {
|
||||
parentID = folder.ID
|
||||
}
|
||||
|
||||
bookmark := bookmarkReq2Model(req, parentID)
|
||||
|
||||
bookmark := bookmarkReq2Model(req)
|
||||
bookmark.ExternalID = id // 设置外部ID
|
||||
if err := db.Create(&bookmark).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, api.Error{
|
||||
Errtype: "DatabaseError",
|
||||
@ -228,61 +148,13 @@ func (b *BookMarksImpl) CreateBookmark(c *gin.Context) {
|
||||
c.JSON(http.StatusCreated, response)
|
||||
}
|
||||
|
||||
// CreateFolder implements api.ServerInterface.
|
||||
func (b *BookMarksImpl) CreateFolder(c *gin.Context) {
|
||||
var db = b.db
|
||||
var req api.FolderRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, api.Error{
|
||||
Errtype: "ParameterError",
|
||||
Message: "Invalid request parameters",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var parentID int64
|
||||
if folder, err := b.GetFolderDefaultRoot(req.ParentId); err != nil || folder == nil {
|
||||
c.JSON(http.StatusNotFound, api.Error{
|
||||
Errtype: "NotFoundError",
|
||||
Message: "Parent folder not found",
|
||||
})
|
||||
return
|
||||
} else {
|
||||
parentID = folder.ID
|
||||
}
|
||||
|
||||
// 创建文件夹
|
||||
folder := folderReq2Model(req, &parentID)
|
||||
|
||||
if err := db.Create(&folder).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, api.Error{
|
||||
Errtype: "DatabaseError",
|
||||
Message: "Failed to create folder",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
response := folderModel2Res(folder)
|
||||
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
|
||||
|
||||
// 查询书签是否存在
|
||||
if err := db.First(&bookmark, id).Error; err != nil {
|
||||
// FIXME maybe use 204 means already deleted status is same as delete
|
||||
c.JSON(http.StatusNotFound, api.Error{
|
||||
Errtype: "NotFoundError",
|
||||
Message: "Bookmark not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 删除书签
|
||||
if err := db.Delete(&bookmark).Error; err != nil {
|
||||
// 使用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",
|
||||
@ -293,72 +165,13 @@ func (b *BookMarksImpl) DeleteBookmark(c *gin.Context, id int64) {
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// DeleteFolder implements api.ServerInterface.
|
||||
func (b *BookMarksImpl) DeleteFolder(c *gin.Context, id int64) {
|
||||
var db = b.db
|
||||
|
||||
var folder models.Folder
|
||||
|
||||
// 查询文件夹是否存在
|
||||
if err := db.First(&folder, id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, api.Error{
|
||||
Errtype: "NotFoundError",
|
||||
Message: "Folder not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if folder.ParentID == nil {
|
||||
c.JSON(http.StatusBadRequest, api.Error{
|
||||
Errtype: "ParameterError",
|
||||
Message: "Cannot delete root folder",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 检查文件夹是否为空
|
||||
var subFolderCount int64
|
||||
db.Model(&models.Folder{}).Where("parent_path_id = ?", id).Count(&subFolderCount)
|
||||
|
||||
var bookmarkCount int64
|
||||
db.Model(&models.Bookmark{}).Where("parent_path_id = ?", id).Count(&bookmarkCount)
|
||||
|
||||
// 如果文件夹不为空,拒绝删除
|
||||
if subFolderCount > 0 || bookmarkCount > 0 {
|
||||
c.JSON(http.StatusBadRequest, api.Error{
|
||||
Errtype: "ParameterError",
|
||||
Message: "Cannot delete non-empty folder, please delete contents first",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 删除空文件夹
|
||||
if err := db.Delete(&folder).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, api.Error{
|
||||
Errtype: "DatabaseError",
|
||||
Message: "Failed to delete folder",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// DeleteFolderContent implements api.ServerInterface.
|
||||
func (b *BookMarksImpl) DeleteFolderContent(c *gin.Context, id int64, params api.DeleteFolderContentParams) {
|
||||
c.JSON(http.StatusNotImplemented, api.Error{
|
||||
Errtype: "error",
|
||||
Message: "Not implemented",
|
||||
})
|
||||
}
|
||||
|
||||
// GetBookmark implements api.ServerInterface.
|
||||
func (b *BookMarksImpl) GetBookmark(c *gin.Context, id int64) {
|
||||
var db = b.db
|
||||
var bookmark models.Bookmark
|
||||
|
||||
// 查询书签
|
||||
if err := db.First(&bookmark, id).Error; err != nil {
|
||||
// 使用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",
|
||||
@ -371,91 +184,6 @@ func (b *BookMarksImpl) GetBookmark(c *gin.Context, id int64) {
|
||||
c.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
// GetFolderContent implements api.ServerInterface.
|
||||
func (b *BookMarksImpl) GetFolderContent(c *gin.Context, id int64) {
|
||||
var db = b.db
|
||||
|
||||
// 检查文件夹是否存在
|
||||
var folder models.Folder
|
||||
if err := db.First(&folder, id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, api.Error{
|
||||
Errtype: "NotFoundError",
|
||||
Message: "Folder not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 查询子文件夹
|
||||
var subFolders []models.Folder
|
||||
db.Where("parent_path_id = ?", id).Find(&subFolders)
|
||||
|
||||
// 查询书签
|
||||
var bookmarks []models.Bookmark
|
||||
db.Where("parent_path_id = ?", id).Find(&bookmarks)
|
||||
|
||||
// 构造子文件夹响应列表
|
||||
var subFolderResponses []api.FolderBriefResponse
|
||||
for _, f := range subFolders {
|
||||
subFolderResponses = append(subFolderResponses, api.FolderBriefResponse{
|
||||
Id: f.ID,
|
||||
Name: f.Name,
|
||||
})
|
||||
}
|
||||
|
||||
// 构造书签响应列表
|
||||
var bookmarkResponses []api.BookmarkBriefResponse
|
||||
for _, bm := range bookmarks {
|
||||
bookmarkResponses = append(bookmarkResponses, api.BookmarkBriefResponse{
|
||||
Id: bm.ID,
|
||||
Name: bm.Name,
|
||||
})
|
||||
}
|
||||
|
||||
// 构造响应
|
||||
response := api.FolderContentResponse{
|
||||
SubFolders: subFolderResponses,
|
||||
Bookmarks: bookmarkResponses,
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
// GetFolderInfo implements api.ServerInterface.
|
||||
func (b *BookMarksImpl) GetFolderInfo(c *gin.Context, id int64) {
|
||||
var db = b.db
|
||||
var folder models.Folder
|
||||
|
||||
// 查询文件夹
|
||||
if err := db.First(&folder, id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, api.Error{
|
||||
Errtype: "NotFoundError",
|
||||
Message: "Folder not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 统计子文件夹数量
|
||||
var subFolderCount int64
|
||||
db.Model(&models.Folder{}).Where("parent_path_id = ?", id).Count(&subFolderCount)
|
||||
|
||||
// 统计书签数量
|
||||
var bookmarkCount int64
|
||||
db.Model(&models.Bookmark{}).Where("parent_path_id = ?", id).Count(&bookmarkCount)
|
||||
|
||||
// 构造响应
|
||||
response := api.FolderResponse{
|
||||
Id: folder.ID,
|
||||
Name: folder.Name,
|
||||
ParentId: folder.ParentID,
|
||||
CreatedAt: folder.CreatedAt,
|
||||
UpdatedAt: folder.UpdatedAt,
|
||||
SubFolderCount: int(subFolderCount),
|
||||
BookmarkCount: int(bookmarkCount),
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
// UpdateBookmark implements api.ServerInterface.
|
||||
func (b *BookMarksImpl) UpdateBookmark(c *gin.Context, id int64) {
|
||||
var db = b.db
|
||||
@ -470,9 +198,9 @@ func (b *BookMarksImpl) UpdateBookmark(c *gin.Context, id int64) {
|
||||
return
|
||||
}
|
||||
|
||||
// 查找要更新的书签
|
||||
// 查找要更新的书签(使用ExternalID)
|
||||
var bookmark models.Bookmark
|
||||
if err := db.First(&bookmark, id).Error; err != nil {
|
||||
if err := db.Where("external_id = ?", id).First(&bookmark).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, api.Error{
|
||||
Errtype: "NotFoundError",
|
||||
Message: "Bookmark not found",
|
||||
@ -494,19 +222,6 @@ func (b *BookMarksImpl) UpdateBookmark(c *gin.Context, id int64) {
|
||||
bookmark.Description = req.Description
|
||||
}
|
||||
|
||||
// 更新父文件夹ID(如果提供且有效)
|
||||
if req.ParentId != nil && *req.ParentId != 0 {
|
||||
var parentFolder models.Folder
|
||||
if err := db.First(&parentFolder, *req.ParentId).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, api.Error{
|
||||
Errtype: "NotFoundError",
|
||||
Message: "Parent folder not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
bookmark.ParentID = *req.ParentId
|
||||
}
|
||||
|
||||
// 保存更新
|
||||
if err := db.Save(&bookmark).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, api.Error{
|
||||
@ -521,88 +236,5 @@ func (b *BookMarksImpl) UpdateBookmark(c *gin.Context, id int64) {
|
||||
c.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
// UpdateFolder implements api.ServerInterface.
|
||||
func (b *BookMarksImpl) UpdateFolder(c *gin.Context, id int64) {
|
||||
var db = b.db
|
||||
var req api.FolderRequest
|
||||
|
||||
// 绑定请求参数
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, api.Error{
|
||||
Errtype: "ParameterError",
|
||||
Message: "Invalid request parameters",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 查找要更新的文件夹
|
||||
var folder models.Folder
|
||||
if err := db.First(&folder, id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, api.Error{
|
||||
Errtype: "NotFoundError",
|
||||
Message: "Folder not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 更新文件夹名称(如果提供)
|
||||
if req.Name != "" {
|
||||
folder.Name = req.Name
|
||||
}
|
||||
|
||||
// 更新父文件夹ID(如果提供且有效)
|
||||
if req.ParentId != nil && *req.ParentId != 0 {
|
||||
// 不能将文件夹设置为自己的子文件夹
|
||||
if *req.ParentId == id {
|
||||
c.JSON(http.StatusBadRequest, api.Error{
|
||||
Errtype: "ParameterError",
|
||||
Message: "Cannot set folder as its own parent",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var parentFolder models.Folder
|
||||
if err := db.First(&parentFolder, *req.ParentId).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, api.Error{
|
||||
Errtype: "NotFoundError",
|
||||
Message: "Parent folder not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
folder.ParentID = req.ParentId
|
||||
}
|
||||
|
||||
// 保存更新
|
||||
if err := db.Save(&folder).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, api.Error{
|
||||
Errtype: "DatabaseError",
|
||||
Message: "Failed to update folder",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 统计子文件夹数量
|
||||
var subFolderCount int64
|
||||
db.Model(&models.Folder{}).Where("parent_path_id = ?", id).Count(&subFolderCount)
|
||||
|
||||
// 统计书签数量
|
||||
var bookmarkCount int64
|
||||
db.Model(&models.Bookmark{}).Where("parent_path_id = ?", id).Count(&bookmarkCount)
|
||||
|
||||
// 构造响应
|
||||
response := folderModel2Res(folder)
|
||||
c.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
// ExportFolderTree implements api.ServerInterface.
|
||||
func (b *BookMarksImpl) ExportFolderTree(c *gin.Context) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// ImportFolderTree implements api.ServerInterface.
|
||||
func (b *BookMarksImpl) ImportFolderTree(c *gin.Context) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// Make sure we conform to ServerInterface
|
||||
var _ api.ServerInterface = (*BookMarksImpl)(nil)
|
||||
|
Reference in New Issue
Block a user