2023-07-06 21:56:42 +08:00
|
|
|
package v1
|
2023-05-01 16:09:41 +08:00
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
|
2023-07-06 21:56:42 +08:00
|
|
|
"github.com/labstack/echo/v4"
|
2023-08-04 21:55:07 +08:00
|
|
|
"github.com/usememos/memos/common/util"
|
2023-05-01 16:09:41 +08:00
|
|
|
"github.com/usememos/memos/store"
|
2023-07-06 21:56:42 +08:00
|
|
|
)
|
2023-05-01 16:09:41 +08:00
|
|
|
|
2023-07-06 21:56:42 +08:00
|
|
|
type MemoRelationType string
|
|
|
|
|
|
|
|
const (
|
|
|
|
MemoRelationReference MemoRelationType = "REFERENCE"
|
|
|
|
MemoRelationAdditional MemoRelationType = "ADDITIONAL"
|
2023-05-01 16:09:41 +08:00
|
|
|
)
|
|
|
|
|
2023-07-06 21:56:42 +08:00
|
|
|
type MemoRelation struct {
|
2023-08-04 21:55:07 +08:00
|
|
|
MemoID int32 `json:"memoId"`
|
|
|
|
RelatedMemoID int32 `json:"relatedMemoId"`
|
2023-07-06 21:56:42 +08:00
|
|
|
Type MemoRelationType `json:"type"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type UpsertMemoRelationRequest struct {
|
2023-08-04 21:55:07 +08:00
|
|
|
RelatedMemoID int32 `json:"relatedMemoId"`
|
2023-07-06 21:56:42 +08:00
|
|
|
Type MemoRelationType `json:"type"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *APIV1Service) registerMemoRelationRoutes(g *echo.Group) {
|
2023-05-01 16:09:41 +08:00
|
|
|
g.POST("/memo/:memoId/relation", func(c echo.Context) error {
|
|
|
|
ctx := c.Request().Context()
|
2023-08-04 21:55:07 +08:00
|
|
|
memoID, err := util.ConvertStringToInt32(c.Param("memoId"))
|
2023-05-01 16:09:41 +08:00
|
|
|
if err != nil {
|
|
|
|
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("ID is not a number: %s", c.Param("memoId"))).SetInternal(err)
|
|
|
|
}
|
|
|
|
|
2023-07-06 21:56:42 +08:00
|
|
|
request := &UpsertMemoRelationRequest{}
|
|
|
|
if err := json.NewDecoder(c.Request().Body).Decode(request); err != nil {
|
2023-05-01 16:09:41 +08:00
|
|
|
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted post memo relation request").SetInternal(err)
|
|
|
|
}
|
|
|
|
|
2023-07-06 21:56:42 +08:00
|
|
|
memoRelation, err := s.Store.UpsertMemoRelation(ctx, &store.MemoRelation{
|
2023-05-01 16:09:41 +08:00
|
|
|
MemoID: memoID,
|
2023-07-06 21:56:42 +08:00
|
|
|
RelatedMemoID: request.RelatedMemoID,
|
|
|
|
Type: store.MemoRelationType(request.Type),
|
2023-05-01 16:09:41 +08:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to upsert memo relation").SetInternal(err)
|
|
|
|
}
|
2023-07-06 21:56:42 +08:00
|
|
|
return c.JSON(http.StatusOK, memoRelation)
|
2023-05-01 16:09:41 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
g.GET("/memo/:memoId/relation", func(c echo.Context) error {
|
|
|
|
ctx := c.Request().Context()
|
2023-08-04 21:55:07 +08:00
|
|
|
memoID, err := util.ConvertStringToInt32(c.Param("memoId"))
|
2023-05-01 16:09:41 +08:00
|
|
|
if err != nil {
|
|
|
|
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("ID is not a number: %s", c.Param("memoId"))).SetInternal(err)
|
|
|
|
}
|
|
|
|
|
2023-07-06 21:56:42 +08:00
|
|
|
memoRelationList, err := s.Store.ListMemoRelations(ctx, &store.FindMemoRelation{
|
2023-05-01 16:09:41 +08:00
|
|
|
MemoID: &memoID,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to list memo relations").SetInternal(err)
|
|
|
|
}
|
2023-07-06 21:56:42 +08:00
|
|
|
return c.JSON(http.StatusOK, memoRelationList)
|
2023-05-01 16:09:41 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
g.DELETE("/memo/:memoId/relation/:relatedMemoId/type/:relationType", func(c echo.Context) error {
|
|
|
|
ctx := c.Request().Context()
|
2023-08-04 21:55:07 +08:00
|
|
|
memoID, err := util.ConvertStringToInt32(c.Param("memoId"))
|
2023-05-01 16:09:41 +08:00
|
|
|
if err != nil {
|
|
|
|
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Memo ID is not a number: %s", c.Param("memoId"))).SetInternal(err)
|
|
|
|
}
|
2023-08-04 21:55:07 +08:00
|
|
|
relatedMemoID, err := util.ConvertStringToInt32(c.Param("relatedMemoId"))
|
2023-05-01 16:09:41 +08:00
|
|
|
if err != nil {
|
|
|
|
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Related memo ID is not a number: %s", c.Param("resourceId"))).SetInternal(err)
|
|
|
|
}
|
|
|
|
relationType := store.MemoRelationType(c.Param("relationType"))
|
|
|
|
|
2023-07-06 21:56:42 +08:00
|
|
|
if err := s.Store.DeleteMemoRelation(ctx, &store.DeleteMemoRelation{
|
2023-05-01 16:09:41 +08:00
|
|
|
MemoID: &memoID,
|
|
|
|
RelatedMemoID: &relatedMemoID,
|
|
|
|
Type: &relationType,
|
|
|
|
}); err != nil {
|
|
|
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to delete memo relation").SetInternal(err)
|
|
|
|
}
|
|
|
|
return c.JSON(http.StatusOK, true)
|
|
|
|
})
|
|
|
|
}
|
2023-05-25 21:50:37 +08:00
|
|
|
|
2023-07-06 21:56:42 +08:00
|
|
|
func convertMemoRelationFromStore(memoRelation *store.MemoRelation) *MemoRelation {
|
|
|
|
return &MemoRelation{
|
2023-05-25 21:50:37 +08:00
|
|
|
MemoID: memoRelation.MemoID,
|
|
|
|
RelatedMemoID: memoRelation.RelatedMemoID,
|
2023-07-06 21:56:42 +08:00
|
|
|
Type: MemoRelationType(memoRelation.Type),
|
2023-05-25 21:50:37 +08:00
|
|
|
}
|
|
|
|
}
|