Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
6007f48b
Commit
6007f48b
authored
Sep 26, 2023
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: retire memo resource relation table
parent
4f10198e
Changes
21
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
126 additions
and
567 deletions
+126
-567
memo.go
api/v1/memo.go
+9
-10
memo_resource.go
api/v1/memo_resource.go
+0
-179
resource.go
api/v1/resource.go
+14
-56
v1.go
api/v1/v1.go
+0
-1
resource_service.go
api/v2/resource_service.go
+7
-7
resource_service.proto
proto/api/v2/resource_service.proto
+1
-1
README.md
proto/gen/api/v2/README.md
+1
-1
resource_service.pb.go
proto/gen/api/v2/resource_service.pb.go
+41
-43
telegram.go
server/integration/telegram.go
+2
-10
LATEST__SCHEMA.sql
store/db/migration/dev/LATEST__SCHEMA.sql
+3
-9
00__add_memo_id_to_resource.sql
store/db/migration/prod/0.16/00__add_memo_id_to_resource.sql
+13
-0
memo.go
store/memo.go
+2
-2
memo_resource.go
store/memo_resource.go
+0
-168
resource.go
store/resource.go
+5
-4
resource.go
store/sqlite/resource.go
+19
-25
store.go
store/store.go
+0
-3
resource_test.go
test/store/resource_test.go
+0
-11
index.tsx
web/src/components/MemoEditor/index.tsx
+4
-2
api.ts
web/src/helpers/api.ts
+0
-14
resource.ts
web/src/store/module/resource.ts
+4
-21
resource.d.ts
web/src/types/modules/resource.d.ts
+1
-0
No files found.
api/v1/memo.go
View file @
6007f48b
...
@@ -319,9 +319,9 @@ func (s *APIV1Service) CreateMemo(c echo.Context) error {
...
@@ -319,9 +319,9 @@ func (s *APIV1Service) CreateMemo(c echo.Context) error {
}
}
for
_
,
resourceID
:=
range
createMemoRequest
.
ResourceIDList
{
for
_
,
resourceID
:=
range
createMemoRequest
.
ResourceIDList
{
if
_
,
err
:=
s
.
Store
.
Up
sertMemoResource
(
ctx
,
&
store
.
UpsertMemo
Resource
{
if
_
,
err
:=
s
.
Store
.
Up
dateResource
(
ctx
,
&
store
.
Update
Resource
{
MemoID
:
memo
.
ID
,
ID
:
resource
ID
,
ResourceID
:
resource
ID
,
MemoID
:
&
memo
.
ID
,
});
err
!=
nil
{
});
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed to upsert memo resource"
)
.
SetInternal
(
err
)
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed to upsert memo resource"
)
.
SetInternal
(
err
)
}
}
...
@@ -694,19 +694,18 @@ func (s *APIV1Service) UpdateMemo(c echo.Context) error {
...
@@ -694,19 +694,18 @@ func (s *APIV1Service) UpdateMemo(c echo.Context) error {
if
patchMemoRequest
.
ResourceIDList
!=
nil
{
if
patchMemoRequest
.
ResourceIDList
!=
nil
{
addedResourceIDList
,
removedResourceIDList
:=
getIDListDiff
(
memo
.
ResourceIDList
,
patchMemoRequest
.
ResourceIDList
)
addedResourceIDList
,
removedResourceIDList
:=
getIDListDiff
(
memo
.
ResourceIDList
,
patchMemoRequest
.
ResourceIDList
)
for
_
,
resourceID
:=
range
addedResourceIDList
{
for
_
,
resourceID
:=
range
addedResourceIDList
{
if
_
,
err
:=
s
.
Store
.
Up
sertMemoResource
(
ctx
,
&
store
.
UpsertMemo
Resource
{
if
_
,
err
:=
s
.
Store
.
Up
dateResource
(
ctx
,
&
store
.
Update
Resource
{
MemoID
:
memo
.
ID
,
ID
:
resource
ID
,
ResourceID
:
resource
ID
,
MemoID
:
&
memo
.
ID
,
});
err
!=
nil
{
});
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed to upsert memo resource"
)
.
SetInternal
(
err
)
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed to upsert memo resource"
)
.
SetInternal
(
err
)
}
}
}
}
for
_
,
resourceID
:=
range
removedResourceIDList
{
for
_
,
resourceID
:=
range
removedResourceIDList
{
if
err
:=
s
.
Store
.
DeleteMemoResource
(
ctx
,
&
store
.
DeleteMemoResource
{
if
err
:=
s
.
Store
.
DeleteResource
(
ctx
,
&
store
.
DeleteResource
{
MemoID
:
&
memo
.
ID
,
ID
:
resourceID
,
ResourceID
:
&
resourceID
,
});
err
!=
nil
{
});
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed to delete
memo
resource"
)
.
SetInternal
(
err
)
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed to delete resource"
)
.
SetInternal
(
err
)
}
}
}
}
}
}
...
...
api/v1/memo_resource.go
deleted
100644 → 0
View file @
4f10198e
package
v1
import
(
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/labstack/echo/v4"
"github.com/usememos/memos/common/util"
"github.com/usememos/memos/store"
)
type
MemoResource
struct
{
MemoID
int32
`json:"memoId"`
ResourceID
int32
`json:"resourceId"`
CreatedTs
int64
`json:"createdTs"`
UpdatedTs
int64
`json:"updatedTs"`
}
type
UpsertMemoResourceRequest
struct
{
ResourceID
int32
`json:"resourceId"`
UpdatedTs
*
int64
`json:"updatedTs"`
}
type
MemoResourceFind
struct
{
MemoID
*
int32
ResourceID
*
int32
}
type
MemoResourceDelete
struct
{
MemoID
*
int32
ResourceID
*
int32
}
func
(
s
*
APIV1Service
)
registerMemoResourceRoutes
(
g
*
echo
.
Group
)
{
g
.
GET
(
"/memo/:memoId/resource"
,
s
.
GetMemoResourceList
)
g
.
POST
(
"/memo/:memoId/resource"
,
s
.
BindMemoResource
)
g
.
DELETE
(
"/memo/:memoId/resource/:resourceId"
,
s
.
UnbindMemoResource
)
}
// GetMemoResourceList godoc
//
// @Summary Get resource list of a memo
// @Tags memo-resource
// @Accept json
// @Produce json
// @Param memoId path int true "ID of memo to fetch resource list from"
// @Success 200 {object} []Resource "Memo resource list"
// @Failure 400 {object} nil "ID is not a number: %s"
// @Failure 500 {object} nil "Failed to fetch resource list"
// @Router /api/v1/memo/{memoId}/resource [GET]
func
(
s
*
APIV1Service
)
GetMemoResourceList
(
c
echo
.
Context
)
error
{
ctx
:=
c
.
Request
()
.
Context
()
memoID
,
err
:=
util
.
ConvertStringToInt32
(
c
.
Param
(
"memoId"
))
if
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusBadRequest
,
fmt
.
Sprintf
(
"ID is not a number: %s"
,
c
.
Param
(
"memoId"
)))
.
SetInternal
(
err
)
}
list
,
err
:=
s
.
Store
.
ListResources
(
ctx
,
&
store
.
FindResource
{
MemoID
:
&
memoID
,
})
if
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed to fetch resource list"
)
.
SetInternal
(
err
)
}
resourceList
:=
[]
*
Resource
{}
for
_
,
resource
:=
range
list
{
resourceList
=
append
(
resourceList
,
convertResourceFromStore
(
resource
))
}
return
c
.
JSON
(
http
.
StatusOK
,
resourceList
)
}
// BindMemoResource godoc
//
// @Summary Bind resource to memo
// @Tags memo-resource
// @Accept json
// @Produce json
// @Param memoId path int true "ID of memo to bind resource to"
// @Param body body UpsertMemoResourceRequest true "Memo resource request object"
// @Success 200 {boolean} true "Memo resource binded"
// @Failure 400 {object} nil "ID is not a number: %s | Malformatted post memo resource request | Resource not found"
// @Failure 401 {object} nil "Missing user in session | Unauthorized to bind this resource"
// @Failure 500 {object} nil "Failed to fetch resource | Failed to upsert memo resource"
// @Router /api/v1/memo/{memoId}/resource [POST]
//
// NOTES:
// - Passing 0 to updatedTs will set it to 0 in the database, which is probably unwanted.
func
(
s
*
APIV1Service
)
BindMemoResource
(
c
echo
.
Context
)
error
{
ctx
:=
c
.
Request
()
.
Context
()
memoID
,
err
:=
util
.
ConvertStringToInt32
(
c
.
Param
(
"memoId"
))
if
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusBadRequest
,
fmt
.
Sprintf
(
"ID is not a number: %s"
,
c
.
Param
(
"memoId"
)))
.
SetInternal
(
err
)
}
userID
,
ok
:=
c
.
Get
(
userIDContextKey
)
.
(
int32
)
if
!
ok
{
return
echo
.
NewHTTPError
(
http
.
StatusUnauthorized
,
"Missing user in session"
)
}
request
:=
&
UpsertMemoResourceRequest
{}
if
err
:=
json
.
NewDecoder
(
c
.
Request
()
.
Body
)
.
Decode
(
request
);
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusBadRequest
,
"Malformatted post memo resource request"
)
.
SetInternal
(
err
)
}
resource
,
err
:=
s
.
Store
.
GetResource
(
ctx
,
&
store
.
FindResource
{
ID
:
&
request
.
ResourceID
,
})
if
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed to fetch resource"
)
.
SetInternal
(
err
)
}
if
resource
==
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusBadRequest
,
"Resource not found"
)
.
SetInternal
(
err
)
}
else
if
resource
.
CreatorID
!=
userID
{
return
echo
.
NewHTTPError
(
http
.
StatusUnauthorized
,
"Unauthorized to bind this resource"
)
.
SetInternal
(
err
)
}
upsert
:=
&
store
.
UpsertMemoResource
{
MemoID
:
memoID
,
ResourceID
:
request
.
ResourceID
,
CreatedTs
:
time
.
Now
()
.
Unix
(),
}
if
request
.
UpdatedTs
!=
nil
{
upsert
.
UpdatedTs
=
request
.
UpdatedTs
}
if
_
,
err
:=
s
.
Store
.
UpsertMemoResource
(
ctx
,
upsert
);
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed to upsert memo resource"
)
.
SetInternal
(
err
)
}
return
c
.
JSON
(
http
.
StatusOK
,
true
)
}
// UnbindMemoResource godoc
//
// @Summary Unbind resource from memo
// @Tags memo-resource
// @Accept json
// @Produce json
// @Param memoId path int true "ID of memo to unbind resource from"
// @Param resourceId path int true "ID of resource to unbind from memo"
// @Success 200 {boolean} true "Memo resource unbinded. *200 is returned even if the reference doesn't exists "
// @Failure 400 {object} nil "Memo ID is not a number: %s | Resource ID is not a number: %s | Memo not found"
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
// @Failure 500 {object} nil "Failed to find memo | Failed to fetch resource list"
// @Router /api/v1/memo/{memoId}/resource/{resourceId} [DELETE]
func
(
s
*
APIV1Service
)
UnbindMemoResource
(
c
echo
.
Context
)
error
{
ctx
:=
c
.
Request
()
.
Context
()
userID
,
ok
:=
c
.
Get
(
userIDContextKey
)
.
(
int32
)
if
!
ok
{
return
echo
.
NewHTTPError
(
http
.
StatusUnauthorized
,
"Missing user in session"
)
}
memoID
,
err
:=
util
.
ConvertStringToInt32
(
c
.
Param
(
"memoId"
))
if
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusBadRequest
,
fmt
.
Sprintf
(
"Memo ID is not a number: %s"
,
c
.
Param
(
"memoId"
)))
.
SetInternal
(
err
)
}
resourceID
,
err
:=
util
.
ConvertStringToInt32
(
c
.
Param
(
"resourceId"
))
if
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusBadRequest
,
fmt
.
Sprintf
(
"Resource ID is not a number: %s"
,
c
.
Param
(
"resourceId"
)))
.
SetInternal
(
err
)
}
memo
,
err
:=
s
.
Store
.
GetMemo
(
ctx
,
&
store
.
FindMemo
{
ID
:
&
memoID
,
})
if
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed to find memo"
)
.
SetInternal
(
err
)
}
if
memo
==
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusBadRequest
,
"Memo not found"
)
}
if
memo
.
CreatorID
!=
userID
{
return
echo
.
NewHTTPError
(
http
.
StatusUnauthorized
,
"Unauthorized"
)
}
if
err
:=
s
.
Store
.
DeleteMemoResource
(
ctx
,
&
store
.
DeleteMemoResource
{
MemoID
:
&
memoID
,
ResourceID
:
&
resourceID
,
});
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed to fetch resource list"
)
.
SetInternal
(
err
)
}
return
c
.
JSON
(
http
.
StatusOK
,
true
)
}
api/v1/resource.go
View file @
6007f48b
...
@@ -384,17 +384,6 @@ func (s *APIV1Service) streamResource(c echo.Context) error {
...
@@ -384,17 +384,6 @@ func (s *APIV1Service) streamResource(c echo.Context) error {
return
echo
.
NewHTTPError
(
http
.
StatusBadRequest
,
fmt
.
Sprintf
(
"ID is not a number: %s"
,
c
.
Param
(
"resourceId"
)))
.
SetInternal
(
err
)
return
echo
.
NewHTTPError
(
http
.
StatusBadRequest
,
fmt
.
Sprintf
(
"ID is not a number: %s"
,
c
.
Param
(
"resourceId"
)))
.
SetInternal
(
err
)
}
}
resourceVisibility
,
err
:=
checkResourceVisibility
(
ctx
,
s
.
Store
,
resourceID
)
if
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusBadRequest
,
"Failed to get resource visibility"
)
.
SetInternal
(
err
)
}
// Protected resource require a logined user
userID
,
ok
:=
c
.
Get
(
userIDContextKey
)
.
(
int32
)
if
resourceVisibility
==
store
.
Protected
&&
(
!
ok
||
userID
<=
0
)
{
return
echo
.
NewHTTPError
(
http
.
StatusUnauthorized
,
"Resource visibility not match"
)
.
SetInternal
(
err
)
}
resource
,
err
:=
s
.
Store
.
GetResource
(
ctx
,
&
store
.
FindResource
{
resource
,
err
:=
s
.
Store
.
GetResource
(
ctx
,
&
store
.
FindResource
{
ID
:
&
resourceID
,
ID
:
&
resourceID
,
GetBlob
:
true
,
GetBlob
:
true
,
...
@@ -405,10 +394,20 @@ func (s *APIV1Service) streamResource(c echo.Context) error {
...
@@ -405,10 +394,20 @@ func (s *APIV1Service) streamResource(c echo.Context) error {
if
resource
==
nil
{
if
resource
==
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusNotFound
,
fmt
.
Sprintf
(
"Resource not found: %d"
,
resourceID
))
return
echo
.
NewHTTPError
(
http
.
StatusNotFound
,
fmt
.
Sprintf
(
"Resource not found: %d"
,
resourceID
))
}
}
// Check the related memo visibility.
// Private resource require logined user is the creator
if
resource
.
MemoID
!=
nil
{
if
resourceVisibility
==
store
.
Private
&&
(
!
ok
||
userID
!=
resource
.
CreatorID
)
{
memo
,
err
:=
s
.
Store
.
GetMemo
(
ctx
,
&
store
.
FindMemo
{
return
echo
.
NewHTTPError
(
http
.
StatusUnauthorized
,
"Resource visibility not match"
)
.
SetInternal
(
err
)
ID
:
resource
.
MemoID
,
})
if
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
fmt
.
Sprintf
(
"Failed to find memo by ID: %v"
,
resource
.
MemoID
))
.
SetInternal
(
err
)
}
if
memo
!=
nil
&&
memo
.
Visibility
!=
store
.
Public
{
userID
,
ok
:=
c
.
Get
(
userIDContextKey
)
.
(
int32
)
if
!
ok
||
(
memo
.
Visibility
==
store
.
Private
&&
userID
!=
resource
.
CreatorID
)
{
return
echo
.
NewHTTPError
(
http
.
StatusUnauthorized
,
"Resource visibility not match"
)
}
}
}
}
blob
:=
resource
.
Blob
blob
:=
resource
.
Blob
...
@@ -542,47 +541,6 @@ func getOrGenerateThumbnailImage(srcBlob []byte, dstPath string) ([]byte, error)
...
@@ -542,47 +541,6 @@ func getOrGenerateThumbnailImage(srcBlob []byte, dstPath string) ([]byte, error)
return
dstBlob
,
nil
return
dstBlob
,
nil
}
}
func
checkResourceVisibility
(
ctx
context
.
Context
,
s
*
store
.
Store
,
resourceID
int32
)
(
store
.
Visibility
,
error
)
{
memoResources
,
err
:=
s
.
ListMemoResources
(
ctx
,
&
store
.
FindMemoResource
{
ResourceID
:
&
resourceID
,
})
if
err
!=
nil
{
return
store
.
Private
,
err
}
// If resource is belongs to no memo, it'll always PRIVATE.
if
len
(
memoResources
)
==
0
{
return
store
.
Private
,
nil
}
memoIDs
:=
make
([]
int32
,
0
,
len
(
memoResources
))
for
_
,
memoResource
:=
range
memoResources
{
memoIDs
=
append
(
memoIDs
,
memoResource
.
MemoID
)
}
visibilityList
,
err
:=
s
.
FindMemosVisibilityList
(
ctx
,
memoIDs
)
if
err
!=
nil
{
return
store
.
Private
,
err
}
var
isProtected
bool
for
_
,
visibility
:=
range
visibilityList
{
// If any memo is PUBLIC, resource should be PUBLIC too.
if
visibility
==
store
.
Public
{
return
store
.
Public
,
nil
}
if
visibility
==
store
.
Protected
{
isProtected
=
true
}
}
if
isProtected
{
return
store
.
Protected
,
nil
}
return
store
.
Private
,
nil
}
func
convertResourceFromStore
(
resource
*
store
.
Resource
)
*
Resource
{
func
convertResourceFromStore
(
resource
*
store
.
Resource
)
*
Resource
{
return
&
Resource
{
return
&
Resource
{
ID
:
resource
.
ID
,
ID
:
resource
.
ID
,
...
...
api/v1/v1.go
View file @
6007f48b
...
@@ -58,7 +58,6 @@ func (s *APIV1Service) Register(rootGroup *echo.Group) {
...
@@ -58,7 +58,6 @@ func (s *APIV1Service) Register(rootGroup *echo.Group) {
s
.
registerResourceRoutes
(
apiV1Group
)
s
.
registerResourceRoutes
(
apiV1Group
)
s
.
registerMemoRoutes
(
apiV1Group
)
s
.
registerMemoRoutes
(
apiV1Group
)
s
.
registerMemoOrganizerRoutes
(
apiV1Group
)
s
.
registerMemoOrganizerRoutes
(
apiV1Group
)
s
.
registerMemoResourceRoutes
(
apiV1Group
)
s
.
registerMemoRelationRoutes
(
apiV1Group
)
s
.
registerMemoRelationRoutes
(
apiV1Group
)
// Register public routes.
// Register public routes.
...
...
api/v2/resource_service.go
View file @
6007f48b
...
@@ -53,6 +53,6 @@ func convertResourceFromStore(resource *store.Resource) *apiv2pb.Resource {
...
@@ -53,6 +53,6 @@ func convertResourceFromStore(resource *store.Resource) *apiv2pb.Resource {
ExternalLink
:
resource
.
ExternalLink
,
ExternalLink
:
resource
.
ExternalLink
,
Type
:
resource
.
Type
,
Type
:
resource
.
Type
,
Size
:
resource
.
Size
,
Size
:
resource
.
Size
,
RelatedMemoId
:
resource
.
Related
MemoID
,
MemoId
:
resource
.
MemoID
,
}
}
}
}
proto/api/v2/resource_service.proto
View file @
6007f48b
...
@@ -20,7 +20,7 @@ message Resource {
...
@@ -20,7 +20,7 @@ message Resource {
string
external_link
=
4
;
string
external_link
=
4
;
string
type
=
5
;
string
type
=
5
;
int64
size
=
6
;
int64
size
=
6
;
optional
int32
related_
memo_id
=
7
;
optional
int32
memo_id
=
7
;
}
}
message
ListResourcesRequest
{}
message
ListResourcesRequest
{}
...
...
proto/gen/api/v2/README.md
View file @
6007f48b
...
@@ -262,7 +262,7 @@
...
@@ -262,7 +262,7 @@
| external_link |
[
string
](
#string
)
| | |
| external_link |
[
string
](
#string
)
| | |
| type |
[
string
](
#string
)
| | |
| type |
[
string
](
#string
)
| | |
| size |
[
int64
](
#int64
)
| | |
| size |
[
int64
](
#int64
)
| | |
|
related_
memo_id |
[
int32
](
#int32
)
| optional | |
| memo_id |
[
int32
](
#int32
)
| optional | |
...
...
proto/gen/api/v2/resource_service.pb.go
View file @
6007f48b
...
@@ -33,7 +33,7 @@ type Resource struct {
...
@@ -33,7 +33,7 @@ type Resource struct {
ExternalLink
string
`protobuf:"bytes,4,opt,name=external_link,json=externalLink,proto3" json:"external_link,omitempty"`
ExternalLink
string
`protobuf:"bytes,4,opt,name=external_link,json=externalLink,proto3" json:"external_link,omitempty"`
Type
string
`protobuf:"bytes,5,opt,name=type,proto3" json:"type,omitempty"`
Type
string
`protobuf:"bytes,5,opt,name=type,proto3" json:"type,omitempty"`
Size
int64
`protobuf:"varint,6,opt,name=size,proto3" json:"size,omitempty"`
Size
int64
`protobuf:"varint,6,opt,name=size,proto3" json:"size,omitempty"`
RelatedMemoId
*
int32
`protobuf:"varint,7,opt,name=related_memo_id,json=relatedMemoId,proto3,oneof" json:"related_
memo_id,omitempty"`
MemoId
*
int32
`protobuf:"varint,7,opt,name=memo_id,json=memoId,proto3,oneof" json:"
memo_id,omitempty"`
}
}
func
(
x
*
Resource
)
Reset
()
{
func
(
x
*
Resource
)
Reset
()
{
...
@@ -110,9 +110,9 @@ func (x *Resource) GetSize() int64 {
...
@@ -110,9 +110,9 @@ func (x *Resource) GetSize() int64 {
return
0
return
0
}
}
func
(
x
*
Resource
)
Get
Related
MemoId
()
int32
{
func
(
x
*
Resource
)
GetMemoId
()
int32
{
if
x
!=
nil
&&
x
.
Related
MemoId
!=
nil
{
if
x
!=
nil
&&
x
.
MemoId
!=
nil
{
return
*
x
.
Related
MemoId
return
*
x
.
MemoId
}
}
return
0
return
0
}
}
...
@@ -211,7 +211,7 @@ var file_api_v2_resource_service_proto_rawDesc = []byte{
...
@@ -211,7 +211,7 @@ var file_api_v2_resource_service_proto_rawDesc = []byte{
0x6f
,
0x6f
,
0x67
,
0x6c
,
0x65
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x61
,
0x6e
,
0x6e
,
0x6f
,
0x74
,
0x61
,
0x6f
,
0x6f
,
0x67
,
0x6c
,
0x65
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x61
,
0x6e
,
0x6e
,
0x6f
,
0x74
,
0x61
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x73
,
0x2e
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x1a
,
0x1f
,
0x67
,
0x6f
,
0x6f
,
0x74
,
0x69
,
0x6f
,
0x6e
,
0x73
,
0x2e
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x1a
,
0x1f
,
0x67
,
0x6f
,
0x6f
,
0x67
,
0x6c
,
0x65
,
0x2f
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x62
,
0x75
,
0x66
,
0x2f
,
0x74
,
0x69
,
0x6d
,
0x67
,
0x6c
,
0x65
,
0x2f
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x62
,
0x75
,
0x66
,
0x2f
,
0x74
,
0x69
,
0x6d
,
0x65
,
0x73
,
0x74
,
0x61
,
0x6d
,
0x70
,
0x2e
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x22
,
0x
ff
,
0x01
,
0x0a
,
0x65
,
0x73
,
0x74
,
0x61
,
0x6d
,
0x70
,
0x2e
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x22
,
0x
e8
,
0x01
,
0x0a
,
0x08
,
0x52
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x12
,
0x0e
,
0x0a
,
0x02
,
0x69
,
0x64
,
0x18
,
0x08
,
0x52
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x12
,
0x0e
,
0x0a
,
0x02
,
0x69
,
0x64
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x05
,
0x52
,
0x02
,
0x69
,
0x64
,
0x12
,
0x39
,
0x0a
,
0x0a
,
0x63
,
0x72
,
0x65
,
0x01
,
0x20
,
0x01
,
0x28
,
0x05
,
0x52
,
0x02
,
0x69
,
0x64
,
0x12
,
0x39
,
0x0a
,
0x0a
,
0x63
,
0x72
,
0x65
,
0x61
,
0x74
,
0x65
,
0x64
,
0x5f
,
0x74
,
0x73
,
0x18
,
0x02
,
0x20
,
0x01
,
0x28
,
0x0b
,
0x32
,
0x1a
,
0x2e
,
0x61
,
0x74
,
0x65
,
0x64
,
0x5f
,
0x74
,
0x73
,
0x18
,
0x02
,
0x20
,
0x01
,
0x28
,
0x0b
,
0x32
,
0x1a
,
0x2e
,
...
@@ -223,38 +223,36 @@ var file_api_v2_resource_service_proto_rawDesc = []byte{
...
@@ -223,38 +223,36 @@ var file_api_v2_resource_service_proto_rawDesc = []byte{
0x6b
,
0x18
,
0x04
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x0c
,
0x65
,
0x78
,
0x74
,
0x65
,
0x72
,
0x6e
,
0x61
,
0x6b
,
0x18
,
0x04
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x0c
,
0x65
,
0x78
,
0x74
,
0x65
,
0x72
,
0x6e
,
0x61
,
0x6c
,
0x4c
,
0x69
,
0x6e
,
0x6b
,
0x12
,
0x12
,
0x0a
,
0x04
,
0x74
,
0x79
,
0x70
,
0x65
,
0x18
,
0x05
,
0x20
,
0x6c
,
0x4c
,
0x69
,
0x6e
,
0x6b
,
0x12
,
0x12
,
0x0a
,
0x04
,
0x74
,
0x79
,
0x70
,
0x65
,
0x18
,
0x05
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x04
,
0x74
,
0x79
,
0x70
,
0x65
,
0x12
,
0x12
,
0x0a
,
0x04
,
0x73
,
0x69
,
0x7a
,
0x01
,
0x28
,
0x09
,
0x52
,
0x04
,
0x74
,
0x79
,
0x70
,
0x65
,
0x12
,
0x12
,
0x0a
,
0x04
,
0x73
,
0x69
,
0x7a
,
0x65
,
0x18
,
0x06
,
0x20
,
0x01
,
0x28
,
0x03
,
0x52
,
0x04
,
0x73
,
0x69
,
0x7a
,
0x65
,
0x12
,
0x2b
,
0x0a
,
0x65
,
0x18
,
0x06
,
0x20
,
0x01
,
0x28
,
0x03
,
0x52
,
0x04
,
0x73
,
0x69
,
0x7a
,
0x65
,
0x12
,
0x1c
,
0x0a
,
0x0f
,
0x72
,
0x65
,
0x6c
,
0x61
,
0x74
,
0x65
,
0x64
,
0x5f
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x5f
,
0x69
,
0x64
,
0x07
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x5f
,
0x69
,
0x64
,
0x18
,
0x07
,
0x20
,
0x01
,
0x28
,
0x05
,
0x48
,
0x00
,
0x18
,
0x07
,
0x20
,
0x01
,
0x28
,
0x05
,
0x48
,
0x00
,
0x52
,
0x0d
,
0x72
,
0x65
,
0x6c
,
0x61
,
0x74
,
0x65
,
0x52
,
0x06
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x49
,
0x64
,
0x88
,
0x01
,
0x01
,
0x42
,
0x0a
,
0x0a
,
0x08
,
0x5f
,
0x64
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x49
,
0x64
,
0x88
,
0x01
,
0x01
,
0x42
,
0x12
,
0x0a
,
0x10
,
0x5f
,
0x72
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x5f
,
0x69
,
0x64
,
0x22
,
0x16
,
0x0a
,
0x14
,
0x4c
,
0x69
,
0x73
,
0x74
,
0x52
,
0x65
,
0x6c
,
0x61
,
0x74
,
0x65
,
0x64
,
0x5f
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x5f
,
0x69
,
0x64
,
0x22
,
0x16
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x73
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x22
,
0x0a
,
0x14
,
0x4c
,
0x69
,
0x73
,
0x74
,
0x52
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x73
,
0x52
,
0x4d
,
0x0a
,
0x15
,
0x4c
,
0x69
,
0x73
,
0x74
,
0x52
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x73
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x22
,
0x4d
,
0x0a
,
0x15
,
0x4c
,
0x69
,
0x73
,
0x74
,
0x52
,
0x65
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x12
,
0x34
,
0x0a
,
0x09
,
0x72
,
0x65
,
0x73
,
0x6f
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x73
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x12
,
0x75
,
0x72
,
0x63
,
0x65
,
0x73
,
0x18
,
0x01
,
0x20
,
0x03
,
0x28
,
0x0b
,
0x32
,
0x16
,
0x2e
,
0x6d
,
0x65
,
0x34
,
0x0a
,
0x09
,
0x72
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x73
,
0x18
,
0x01
,
0x20
,
0x03
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x52
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x28
,
0x0b
,
0x32
,
0x16
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x72
,
0x63
,
0x65
,
0x52
,
0x09
,
0x72
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x73
,
0x32
,
0x86
,
0x32
,
0x2e
,
0x52
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x52
,
0x09
,
0x72
,
0x65
,
0x73
,
0x6f
,
0x01
,
0x0a
,
0x0f
,
0x52
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x53
,
0x65
,
0x72
,
0x76
,
0x69
,
0x75
,
0x72
,
0x63
,
0x65
,
0x73
,
0x32
,
0x86
,
0x01
,
0x0a
,
0x0f
,
0x52
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x12
,
0x73
,
0x0a
,
0x0d
,
0x4c
,
0x69
,
0x73
,
0x74
,
0x52
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x53
,
0x65
,
0x72
,
0x76
,
0x69
,
0x63
,
0x65
,
0x12
,
0x73
,
0x0a
,
0x0d
,
0x4c
,
0x69
,
0x73
,
0x63
,
0x65
,
0x73
,
0x12
,
0x22
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x74
,
0x52
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x73
,
0x12
,
0x22
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x76
,
0x32
,
0x2e
,
0x4c
,
0x69
,
0x73
,
0x74
,
0x52
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x73
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x4c
,
0x69
,
0x73
,
0x74
,
0x52
,
0x65
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x1a
,
0x23
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x73
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x1a
,
0x23
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x4c
,
0x69
,
0x73
,
0x74
,
0x52
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x4c
,
0x69
,
0x72
,
0x63
,
0x65
,
0x73
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x22
,
0x19
,
0x82
,
0xd3
,
0x73
,
0x74
,
0x52
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x73
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0xe4
,
0x93
,
0x02
,
0x13
,
0x12
,
0x11
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x2f
,
0x72
,
0x65
,
0x6e
,
0x73
,
0x65
,
0x22
,
0x19
,
0x82
,
0xd3
,
0xe4
,
0x93
,
0x02
,
0x13
,
0x12
,
0x11
,
0x2f
,
0x61
,
0x70
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x73
,
0x42
,
0xac
,
0x01
,
0x0a
,
0x10
,
0x63
,
0x6f
,
0x6d
,
0x2e
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x2f
,
0x72
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x73
,
0x42
,
0xac
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x42
,
0x14
,
0x52
,
0x65
,
0x01
,
0x0a
,
0x10
,
0x63
,
0x6f
,
0x6d
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x53
,
0x65
,
0x72
,
0x76
,
0x69
,
0x63
,
0x65
,
0x50
,
0x72
,
0x6f
,
0x2e
,
0x76
,
0x32
,
0x42
,
0x14
,
0x52
,
0x65
,
0x73
,
0x6f
,
0x75
,
0x72
,
0x63
,
0x65
,
0x53
,
0x65
,
0x72
,
0x74
,
0x6f
,
0x50
,
0x01
,
0x5a
,
0x30
,
0x67
,
0x69
,
0x74
,
0x68
,
0x75
,
0x62
,
0x2e
,
0x63
,
0x6f
,
0x6d
,
0x76
,
0x69
,
0x63
,
0x65
,
0x50
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x50
,
0x01
,
0x5a
,
0x30
,
0x67
,
0x69
,
0x74
,
0x2f
,
0x75
,
0x73
,
0x65
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2f
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2f
,
0x68
,
0x75
,
0x62
,
0x2e
,
0x63
,
0x6f
,
0x6d
,
0x2f
,
0x75
,
0x73
,
0x65
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x2f
,
0x67
,
0x65
,
0x6e
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x2f
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2f
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x2f
,
0x67
,
0x65
,
0x6e
,
0x3b
,
0x61
,
0x70
,
0x69
,
0x76
,
0x32
,
0xa2
,
0x02
,
0x03
,
0x4d
,
0x41
,
0x58
,
0xaa
,
0x02
,
0x0c
,
0x4d
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x3b
,
0x61
,
0x70
,
0x69
,
0x76
,
0x32
,
0xa2
,
0x02
,
0x03
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x41
,
0x70
,
0x69
,
0x2e
,
0x56
,
0x32
,
0xca
,
0x02
,
0x0c
,
0x4d
,
0x65
,
0x4d
,
0x41
,
0x58
,
0xaa
,
0x02
,
0x0c
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x41
,
0x70
,
0x69
,
0x2e
,
0x6d
,
0x6f
,
0x73
,
0x5c
,
0x41
,
0x70
,
0x69
,
0x5c
,
0x56
,
0x32
,
0xe2
,
0x02
,
0x18
,
0x4d
,
0x65
,
0x6d
,
0x56
,
0x32
,
0xca
,
0x02
,
0x0c
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x5c
,
0x41
,
0x70
,
0x69
,
0x5c
,
0x56
,
0x6f
,
0x73
,
0x5c
,
0x41
,
0x70
,
0x69
,
0x5c
,
0x56
,
0x32
,
0x5c
,
0x47
,
0x50
,
0x42
,
0x4d
,
0x65
,
0x74
,
0x32
,
0xe2
,
0x02
,
0x18
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x5c
,
0x41
,
0x70
,
0x69
,
0x5c
,
0x56
,
0x32
,
0x61
,
0x64
,
0x61
,
0x74
,
0x61
,
0xea
,
0x02
,
0x0e
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x3a
,
0x3a
,
0x41
,
0x5c
,
0x47
,
0x50
,
0x42
,
0x4d
,
0x65
,
0x74
,
0x61
,
0x64
,
0x61
,
0x74
,
0x61
,
0xea
,
0x02
,
0x0e
,
0x4d
,
0x70
,
0x69
,
0x3a
,
0x3a
,
0x56
,
0x32
,
0x62
,
0x06
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x33
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x3a
,
0x3a
,
0x41
,
0x70
,
0x69
,
0x3a
,
0x3a
,
0x56
,
0x32
,
0x62
,
0x06
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x33
,
}
}
var
(
var
(
...
...
server/integration/telegram.go
View file @
6007f48b
...
@@ -92,6 +92,7 @@ func (t *TelegramHandler) MessageHandle(ctx context.Context, bot *telegram.Bot,
...
@@ -92,6 +92,7 @@ func (t *TelegramHandler) MessageHandle(ctx context.Context, bot *telegram.Bot,
Filename
:
attachment
.
FileName
,
Filename
:
attachment
.
FileName
,
Type
:
attachment
.
GetMimeType
(),
Type
:
attachment
.
GetMimeType
(),
Size
:
attachment
.
FileSize
,
Size
:
attachment
.
FileSize
,
MemoID
:
&
memoMessage
.
ID
,
}
}
err
:=
apiv1
.
SaveResourceBlob
(
ctx
,
t
.
store
,
&
create
,
bytes
.
NewReader
(
attachment
.
Data
))
err
:=
apiv1
.
SaveResourceBlob
(
ctx
,
t
.
store
,
&
create
,
bytes
.
NewReader
(
attachment
.
Data
))
...
@@ -100,20 +101,11 @@ func (t *TelegramHandler) MessageHandle(ctx context.Context, bot *telegram.Bot,
...
@@ -100,20 +101,11 @@ func (t *TelegramHandler) MessageHandle(ctx context.Context, bot *telegram.Bot,
return
err
return
err
}
}
resource
,
err
:
=
t
.
store
.
CreateResource
(
ctx
,
&
create
)
_
,
err
=
t
.
store
.
CreateResource
(
ctx
,
&
create
)
if
err
!=
nil
{
if
err
!=
nil
{
_
,
err
:=
bot
.
EditMessage
(
ctx
,
message
.
Chat
.
ID
,
reply
.
MessageID
,
fmt
.
Sprintf
(
"Failed to CreateResource: %s"
,
err
),
nil
)
_
,
err
:=
bot
.
EditMessage
(
ctx
,
message
.
Chat
.
ID
,
reply
.
MessageID
,
fmt
.
Sprintf
(
"Failed to CreateResource: %s"
,
err
),
nil
)
return
err
return
err
}
}
_
,
err
=
t
.
store
.
UpsertMemoResource
(
ctx
,
&
store
.
UpsertMemoResource
{
MemoID
:
memoMessage
.
ID
,
ResourceID
:
resource
.
ID
,
})
if
err
!=
nil
{
_
,
err
:=
bot
.
EditMessage
(
ctx
,
message
.
Chat
.
ID
,
reply
.
MessageID
,
fmt
.
Sprintf
(
"Failed to UpsertMemoResource: %s"
,
err
),
nil
)
return
err
}
}
}
keyboard
:=
generateKeyboardForMemoID
(
memoMessage
.
ID
)
keyboard
:=
generateKeyboardForMemoID
(
memoMessage
.
ID
)
...
...
store/db/migration/dev/LATEST__SCHEMA.sql
View file @
6007f48b
...
@@ -81,19 +81,13 @@ CREATE TABLE resource (
...
@@ -81,19 +81,13 @@ CREATE TABLE resource (
external_link
TEXT
NOT
NULL
DEFAULT
''
,
external_link
TEXT
NOT
NULL
DEFAULT
''
,
type
TEXT
NOT
NULL
DEFAULT
''
,
type
TEXT
NOT
NULL
DEFAULT
''
,
size
INTEGER
NOT
NULL
DEFAULT
0
,
size
INTEGER
NOT
NULL
DEFAULT
0
,
internal_path
TEXT
NOT
NULL
DEFAULT
''
internal_path
TEXT
NOT
NULL
DEFAULT
''
,
memo_id
INTEGER
);
);
CREATE
INDEX
idx_resource_creator_id
ON
resource
(
creator_id
);
CREATE
INDEX
idx_resource_creator_id
ON
resource
(
creator_id
);
-- memo_resource
CREATE
INDEX
idx_resource_memo_id
ON
resource
(
memo_id
);
CREATE
TABLE
memo_resource
(
memo_id
INTEGER
NOT
NULL
,
resource_id
INTEGER
NOT
NULL
,
created_ts
BIGINT
NOT
NULL
DEFAULT
(
strftime
(
'%s'
,
'now'
)),
updated_ts
BIGINT
NOT
NULL
DEFAULT
(
strftime
(
'%s'
,
'now'
)),
UNIQUE
(
memo_id
,
resource_id
)
);
-- tag
-- tag
CREATE
TABLE
tag
(
CREATE
TABLE
tag
(
...
...
store/db/migration/prod/0.16/00__add_memo_id_to_resource.sql
0 → 100644
View file @
6007f48b
ALTER
TABLE
resource
ADD
COLUMN
memo_id
INTEGER
;
UPDATE
resource
SET
memo_id
=
(
SELECT
memo_id
FROM
memo_resource
WHERE
resource
.
id
=
memo_resource
.
resource_id
LIMIT
1
);
DROP
TABLE
memo_resource
;
CREATE
INDEX
idx_resource_memo_id
ON
resource
(
memo_id
);
store/memo.go
View file @
6007f48b
...
@@ -175,7 +175,7 @@ func (s *Store) ListMemos(ctx context.Context, find *FindMemo) ([]*Memo, error)
...
@@ -175,7 +175,7 @@ func (s *Store) ListMemos(ctx context.Context, find *FindMemo) ([]*Memo, error)
memo.content AS content,
memo.content AS content,
memo.visibility AS visibility,
memo.visibility AS visibility,
CASE WHEN memo_organizer.pinned = 1 THEN 1 ELSE 0 END AS pinned,
CASE WHEN memo_organizer.pinned = 1 THEN 1 ELSE 0 END AS pinned,
GROUP_CONCAT(
memo_resource.resource_
id) AS resource_id_list,
GROUP_CONCAT(
resource.
id) AS resource_id_list,
(
(
SELECT
SELECT
GROUP_CONCAT(related_memo_id || ':' || type)
GROUP_CONCAT(related_memo_id || ':' || type)
...
@@ -191,7 +191,7 @@ func (s *Store) ListMemos(ctx context.Context, find *FindMemo) ([]*Memo, error)
...
@@ -191,7 +191,7 @@ func (s *Store) ListMemos(ctx context.Context, find *FindMemo) ([]*Memo, error)
LEFT JOIN
LEFT JOIN
memo_organizer ON memo.id = memo_organizer.memo_id
memo_organizer ON memo.id = memo_organizer.memo_id
LEFT JOIN
LEFT JOIN
memo_resource ON memo.id = memo_
resource.memo_id
resource ON memo.id =
resource.memo_id
WHERE `
+
strings
.
Join
(
where
,
" AND "
)
+
`
WHERE `
+
strings
.
Join
(
where
,
" AND "
)
+
`
GROUP BY memo.id
GROUP BY memo.id
ORDER BY `
+
strings
.
Join
(
orders
,
", "
)
+
`
ORDER BY `
+
strings
.
Join
(
orders
,
", "
)
+
`
...
...
store/memo_resource.go
deleted
100644 → 0
View file @
4f10198e
package
store
import
(
"context"
"database/sql"
"strings"
)
type
MemoResource
struct
{
MemoID
int32
ResourceID
int32
CreatedTs
int64
UpdatedTs
int64
}
type
UpsertMemoResource
struct
{
MemoID
int32
ResourceID
int32
CreatedTs
int64
UpdatedTs
*
int64
}
type
FindMemoResource
struct
{
MemoID
*
int32
ResourceID
*
int32
}
type
DeleteMemoResource
struct
{
MemoID
*
int32
ResourceID
*
int32
}
func
(
s
*
Store
)
UpsertMemoResource
(
ctx
context
.
Context
,
upsert
*
UpsertMemoResource
)
(
*
MemoResource
,
error
)
{
set
:=
[]
string
{
"memo_id"
,
"resource_id"
}
args
:=
[]
any
{
upsert
.
MemoID
,
upsert
.
ResourceID
}
placeholder
:=
[]
string
{
"?"
,
"?"
}
if
v
:=
upsert
.
UpdatedTs
;
v
!=
nil
{
set
,
args
,
placeholder
=
append
(
set
,
"updated_ts"
),
append
(
args
,
v
),
append
(
placeholder
,
"?"
)
}
query
:=
`
INSERT INTO memo_resource (
`
+
strings
.
Join
(
set
,
", "
)
+
`
)
VALUES (`
+
strings
.
Join
(
placeholder
,
","
)
+
`)
ON CONFLICT(memo_id, resource_id) DO UPDATE
SET
updated_ts = EXCLUDED.updated_ts
RETURNING memo_id, resource_id, created_ts, updated_ts
`
memoResource
:=
&
MemoResource
{}
if
err
:=
s
.
db
.
QueryRowContext
(
ctx
,
query
,
args
...
)
.
Scan
(
&
memoResource
.
MemoID
,
&
memoResource
.
ResourceID
,
&
memoResource
.
CreatedTs
,
&
memoResource
.
UpdatedTs
,
);
err
!=
nil
{
return
nil
,
err
}
return
memoResource
,
nil
}
func
(
s
*
Store
)
ListMemoResources
(
ctx
context
.
Context
,
find
*
FindMemoResource
)
([]
*
MemoResource
,
error
)
{
where
,
args
:=
[]
string
{
"1 = 1"
},
[]
any
{}
if
v
:=
find
.
MemoID
;
v
!=
nil
{
where
,
args
=
append
(
where
,
"memo_id = ?"
),
append
(
args
,
*
v
)
}
if
v
:=
find
.
ResourceID
;
v
!=
nil
{
where
,
args
=
append
(
where
,
"resource_id = ?"
),
append
(
args
,
*
v
)
}
query
:=
`
SELECT
memo_id,
resource_id,
created_ts,
updated_ts
FROM memo_resource
WHERE `
+
strings
.
Join
(
where
,
" AND "
)
+
`
ORDER BY updated_ts DESC
`
rows
,
err
:=
s
.
db
.
QueryContext
(
ctx
,
query
,
args
...
)
if
err
!=
nil
{
return
nil
,
err
}
defer
rows
.
Close
()
list
:=
make
([]
*
MemoResource
,
0
)
for
rows
.
Next
()
{
var
memoResource
MemoResource
if
err
:=
rows
.
Scan
(
&
memoResource
.
MemoID
,
&
memoResource
.
ResourceID
,
&
memoResource
.
CreatedTs
,
&
memoResource
.
UpdatedTs
,
);
err
!=
nil
{
return
nil
,
err
}
list
=
append
(
list
,
&
memoResource
)
}
if
err
:=
rows
.
Err
();
err
!=
nil
{
return
nil
,
err
}
return
list
,
nil
}
func
(
s
*
Store
)
GetMemoResource
(
ctx
context
.
Context
,
find
*
FindMemoResource
)
(
*
MemoResource
,
error
)
{
list
,
err
:=
s
.
ListMemoResources
(
ctx
,
find
)
if
err
!=
nil
{
return
nil
,
err
}
if
len
(
list
)
==
0
{
return
nil
,
nil
}
memoResource
:=
list
[
0
]
return
memoResource
,
nil
}
func
(
s
*
Store
)
DeleteMemoResource
(
ctx
context
.
Context
,
delete
*
DeleteMemoResource
)
error
{
where
,
args
:=
[]
string
{},
[]
any
{}
if
v
:=
delete
.
MemoID
;
v
!=
nil
{
where
,
args
=
append
(
where
,
"memo_id = ?"
),
append
(
args
,
*
v
)
}
if
v
:=
delete
.
ResourceID
;
v
!=
nil
{
where
,
args
=
append
(
where
,
"resource_id = ?"
),
append
(
args
,
*
v
)
}
stmt
:=
`DELETE FROM memo_resource WHERE `
+
strings
.
Join
(
where
,
" AND "
)
result
,
err
:=
s
.
db
.
ExecContext
(
ctx
,
stmt
,
args
...
)
if
err
!=
nil
{
return
err
}
if
_
,
err
=
result
.
RowsAffected
();
err
!=
nil
{
return
err
}
return
nil
}
func
vacuumMemoResource
(
ctx
context
.
Context
,
tx
*
sql
.
Tx
)
error
{
stmt
:=
`
DELETE FROM
memo_resource
WHERE
memo_id NOT IN (
SELECT
id
FROM
memo
)
OR resource_id NOT IN (
SELECT
id
FROM
resource
)`
_
,
err
:=
tx
.
ExecContext
(
ctx
,
stmt
)
if
err
!=
nil
{
return
err
}
return
nil
}
store/resource.go
View file @
6007f48b
...
@@ -20,9 +20,7 @@ type Resource struct {
...
@@ -20,9 +20,7 @@ type Resource struct {
ExternalLink
string
ExternalLink
string
Type
string
Type
string
Size
int64
Size
int64
MemoID
*
int32
// Related fields
RelatedMemoID
*
int32
}
}
type
FindResource
struct
{
type
FindResource
struct
{
...
@@ -41,11 +39,14 @@ type UpdateResource struct {
...
@@ -41,11 +39,14 @@ type UpdateResource struct {
UpdatedTs
*
int64
UpdatedTs
*
int64
Filename
*
string
Filename
*
string
InternalPath
*
string
InternalPath
*
string
MemoID
*
int32
UnbindMemo
bool
Blob
[]
byte
Blob
[]
byte
}
}
type
DeleteResource
struct
{
type
DeleteResource
struct
{
ID
int32
ID
int32
MemoID
*
int32
}
}
func
(
s
*
Store
)
CreateResource
(
ctx
context
.
Context
,
create
*
Resource
)
(
*
Resource
,
error
)
{
func
(
s
*
Store
)
CreateResource
(
ctx
context
.
Context
,
create
*
Resource
)
(
*
Resource
,
error
)
{
...
...
store/sqlite/resource.go
View file @
6007f48b
...
@@ -4,7 +4,6 @@ import (
...
@@ -4,7 +4,6 @@ import (
"context"
"context"
"database/sql"
"database/sql"
"fmt"
"fmt"
"strconv"
"strings"
"strings"
"github.com/usememos/memos/store"
"github.com/usememos/memos/store"
...
@@ -45,35 +44,33 @@ func (d *Driver) ListResources(ctx context.Context, find *store.FindResource) ([
...
@@ -45,35 +44,33 @@ func (d *Driver) ListResources(ctx context.Context, find *store.FindResource) ([
where
,
args
:=
[]
string
{
"1 = 1"
},
[]
any
{}
where
,
args
:=
[]
string
{
"1 = 1"
},
[]
any
{}
if
v
:=
find
.
ID
;
v
!=
nil
{
if
v
:=
find
.
ID
;
v
!=
nil
{
where
,
args
=
append
(
where
,
"
resource.
id = ?"
),
append
(
args
,
*
v
)
where
,
args
=
append
(
where
,
"id = ?"
),
append
(
args
,
*
v
)
}
}
if
v
:=
find
.
CreatorID
;
v
!=
nil
{
if
v
:=
find
.
CreatorID
;
v
!=
nil
{
where
,
args
=
append
(
where
,
"
resource.
creator_id = ?"
),
append
(
args
,
*
v
)
where
,
args
=
append
(
where
,
"creator_id = ?"
),
append
(
args
,
*
v
)
}
}
if
v
:=
find
.
Filename
;
v
!=
nil
{
if
v
:=
find
.
Filename
;
v
!=
nil
{
where
,
args
=
append
(
where
,
"
resource.
filename = ?"
),
append
(
args
,
*
v
)
where
,
args
=
append
(
where
,
"filename = ?"
),
append
(
args
,
*
v
)
}
}
if
v
:=
find
.
MemoID
;
v
!=
nil
{
if
v
:=
find
.
MemoID
;
v
!=
nil
{
where
,
args
=
append
(
where
,
"
resource.id in (SELECT resource_id FROM memo_resource WHERE memo_id = ?)
"
),
append
(
args
,
*
v
)
where
,
args
=
append
(
where
,
"
memo_id = ?
"
),
append
(
args
,
*
v
)
}
}
if
find
.
HasRelatedMemo
{
if
find
.
HasRelatedMemo
{
where
=
append
(
where
,
"memo_
resource.memo_
id IS NOT NULL"
)
where
=
append
(
where
,
"memo_id IS NOT NULL"
)
}
}
fields
:=
[]
string
{
"
resource.id"
,
"resource.filename"
,
"resource.external_link"
,
"resource.type"
,
"resource.size"
,
"resource.creator_id"
,
"resource.created_ts"
,
"resource.updated_ts"
,
"internal_path
"
}
fields
:=
[]
string
{
"
id"
,
"filename"
,
"external_link"
,
"type"
,
"size"
,
"creator_id"
,
"created_ts"
,
"updated_ts"
,
"internal_path"
,
"memo_id
"
}
if
find
.
GetBlob
{
if
find
.
GetBlob
{
fields
=
append
(
fields
,
"
resource.
blob"
)
fields
=
append
(
fields
,
"blob"
)
}
}
query
:=
fmt
.
Sprintf
(
`
query
:=
fmt
.
Sprintf
(
`
SELECT
SELECT
GROUP_CONCAT(memo_resource.memo_id) as related_memo_ids,
%s
%s
FROM resource
FROM resource
LEFT JOIN memo_resource ON resource.id = memo_resource.resource_id
WHERE %s
WHERE %s
GROUP BY
resource.
id
GROUP BY id
ORDER BY
resource.
created_ts DESC
ORDER BY created_ts DESC
`
,
strings
.
Join
(
fields
,
", "
),
strings
.
Join
(
where
,
" AND "
))
`
,
strings
.
Join
(
fields
,
", "
),
strings
.
Join
(
where
,
" AND "
))
if
find
.
Limit
!=
nil
{
if
find
.
Limit
!=
nil
{
query
=
fmt
.
Sprintf
(
"%s LIMIT %d"
,
query
,
*
find
.
Limit
)
query
=
fmt
.
Sprintf
(
"%s LIMIT %d"
,
query
,
*
find
.
Limit
)
...
@@ -91,9 +88,8 @@ func (d *Driver) ListResources(ctx context.Context, find *store.FindResource) ([
...
@@ -91,9 +88,8 @@ func (d *Driver) ListResources(ctx context.Context, find *store.FindResource) ([
list
:=
make
([]
*
store
.
Resource
,
0
)
list
:=
make
([]
*
store
.
Resource
,
0
)
for
rows
.
Next
()
{
for
rows
.
Next
()
{
resource
:=
store
.
Resource
{}
resource
:=
store
.
Resource
{}
var
relatedMemoIDs
sql
.
NullString
var
memoID
sql
.
NullInt32
dests
:=
[]
any
{
dests
:=
[]
any
{
&
relatedMemoIDs
,
&
resource
.
ID
,
&
resource
.
ID
,
&
resource
.
Filename
,
&
resource
.
Filename
,
&
resource
.
ExternalLink
,
&
resource
.
ExternalLink
,
...
@@ -103,6 +99,7 @@ func (d *Driver) ListResources(ctx context.Context, find *store.FindResource) ([
...
@@ -103,6 +99,7 @@ func (d *Driver) ListResources(ctx context.Context, find *store.FindResource) ([
&
resource
.
CreatedTs
,
&
resource
.
CreatedTs
,
&
resource
.
UpdatedTs
,
&
resource
.
UpdatedTs
,
&
resource
.
InternalPath
,
&
resource
.
InternalPath
,
&
memoID
,
}
}
if
find
.
GetBlob
{
if
find
.
GetBlob
{
dests
=
append
(
dests
,
&
resource
.
Blob
)
dests
=
append
(
dests
,
&
resource
.
Blob
)
...
@@ -110,17 +107,8 @@ func (d *Driver) ListResources(ctx context.Context, find *store.FindResource) ([
...
@@ -110,17 +107,8 @@ func (d *Driver) ListResources(ctx context.Context, find *store.FindResource) ([
if
err
:=
rows
.
Scan
(
dests
...
);
err
!=
nil
{
if
err
:=
rows
.
Scan
(
dests
...
);
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
if
relatedMemoIDs
.
Valid
{
if
memoID
.
Valid
{
relatedMemoIDList
:=
strings
.
Split
(
relatedMemoIDs
.
String
,
","
)
resource
.
MemoID
=
&
memoID
.
Int32
if
len
(
relatedMemoIDList
)
>
0
{
// Only take the first related memo ID.
relatedMemoIDInt
,
err
:=
strconv
.
ParseInt
(
relatedMemoIDList
[
0
],
10
,
32
)
if
err
!=
nil
{
return
nil
,
err
}
relatedMemoID
:=
int32
(
relatedMemoIDInt
)
resource
.
RelatedMemoID
=
&
relatedMemoID
}
}
}
list
=
append
(
list
,
&
resource
)
list
=
append
(
list
,
&
resource
)
}
}
...
@@ -144,6 +132,12 @@ func (d *Driver) UpdateResource(ctx context.Context, update *store.UpdateResourc
...
@@ -144,6 +132,12 @@ func (d *Driver) UpdateResource(ctx context.Context, update *store.UpdateResourc
if
v
:=
update
.
InternalPath
;
v
!=
nil
{
if
v
:=
update
.
InternalPath
;
v
!=
nil
{
set
,
args
=
append
(
set
,
"internal_path = ?"
),
append
(
args
,
*
v
)
set
,
args
=
append
(
set
,
"internal_path = ?"
),
append
(
args
,
*
v
)
}
}
if
v
:=
update
.
MemoID
;
v
!=
nil
{
set
,
args
=
append
(
set
,
"memo_id = ?"
),
append
(
args
,
*
v
)
}
if
update
.
UnbindMemo
{
set
=
append
(
set
,
"memo_id = NULL"
)
}
if
v
:=
update
.
Blob
;
v
!=
nil
{
if
v
:=
update
.
Blob
;
v
!=
nil
{
set
,
args
=
append
(
set
,
"blob = ?"
),
append
(
args
,
v
)
set
,
args
=
append
(
set
,
"blob = ?"
),
append
(
args
,
v
)
}
}
...
...
store/store.go
View file @
6007f48b
...
@@ -109,9 +109,6 @@ func (*Store) vacuumImpl(ctx context.Context, tx *sql.Tx) error {
...
@@ -109,9 +109,6 @@ func (*Store) vacuumImpl(ctx context.Context, tx *sql.Tx) error {
if
err
:=
vacuumMemoOrganizer
(
ctx
,
tx
);
err
!=
nil
{
if
err
:=
vacuumMemoOrganizer
(
ctx
,
tx
);
err
!=
nil
{
return
err
return
err
}
}
if
err
:=
vacuumMemoResource
(
ctx
,
tx
);
err
!=
nil
{
return
err
}
if
err
:=
vacuumMemoRelations
(
ctx
,
tx
);
err
!=
nil
{
if
err
:=
vacuumMemoRelations
(
ctx
,
tx
);
err
!=
nil
{
return
err
return
err
}
}
...
...
test/store/resource_test.go
View file @
6007f48b
...
@@ -31,17 +31,6 @@ func TestResourceStore(t *testing.T) {
...
@@ -31,17 +31,6 @@ func TestResourceStore(t *testing.T) {
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
correctFilename
,
resource
.
Filename
)
require
.
Equal
(
t
,
correctFilename
,
resource
.
Filename
)
require
.
Equal
(
t
,
int32
(
1
),
resource
.
ID
)
require
.
Equal
(
t
,
int32
(
1
),
resource
.
ID
)
_
,
err
=
ts
.
UpsertMemoResource
(
ctx
,
&
store
.
UpsertMemoResource
{
MemoID
:
1
,
ResourceID
:
resource
.
ID
,
})
require
.
NoError
(
t
,
err
)
resource
,
err
=
ts
.
GetResource
(
ctx
,
&
store
.
FindResource
{
ID
:
&
resource
.
ID
,
})
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
*
resource
.
RelatedMemoID
,
int32
(
1
))
notFoundResource
,
err
:=
ts
.
GetResource
(
ctx
,
&
store
.
FindResource
{
notFoundResource
,
err
:=
ts
.
GetResource
(
ctx
,
&
store
.
FindResource
{
Filename
:
&
incorrectFilename
,
Filename
:
&
incorrectFilename
,
...
...
web/src/components/MemoEditor/index.tsx
View file @
6007f48b
...
@@ -3,7 +3,6 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"
...
@@ -3,7 +3,6 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"
import
{
toast
}
from
"react-hot-toast"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
useTranslation
}
from
"react-i18next"
;
import
{
useTranslation
}
from
"react-i18next"
;
import
useLocalStorage
from
"react-use/lib/useLocalStorage"
;
import
useLocalStorage
from
"react-use/lib/useLocalStorage"
;
import
{
upsertMemoResource
}
from
"@/helpers/api"
;
import
{
TAB_SPACE_WIDTH
,
UNKNOWN_ID
}
from
"@/helpers/consts"
;
import
{
TAB_SPACE_WIDTH
,
UNKNOWN_ID
}
from
"@/helpers/consts"
;
import
{
clearContentQueryParam
}
from
"@/helpers/utils"
;
import
{
clearContentQueryParam
}
from
"@/helpers/utils"
;
import
{
getMatchedNodes
}
from
"@/labs/marked"
;
import
{
getMatchedNodes
}
from
"@/labs/marked"
;
...
@@ -223,7 +222,10 @@ const MemoEditor = (props: Props) => {
...
@@ -223,7 +222,10 @@ const MemoEditor = (props: Props) => {
if
(
resource
)
{
if
(
resource
)
{
uploadedResourceList
.
push
(
resource
);
uploadedResourceList
.
push
(
resource
);
if
(
memoId
)
{
if
(
memoId
)
{
await
upsertMemoResource
(
memoId
,
resource
.
id
);
await
resourceStore
.
patchResource
({
id
:
resource
.
id
,
memoId
,
});
}
}
}
}
}
}
...
...
web/src/helpers/api.ts
View file @
6007f48b
...
@@ -155,20 +155,6 @@ export function deleteResourceById(id: ResourceId) {
...
@@ -155,20 +155,6 @@ export function deleteResourceById(id: ResourceId) {
return
axios
.
delete
(
`/api/v1/resource/
${
id
}
`
);
return
axios
.
delete
(
`/api/v1/resource/
${
id
}
`
);
}
}
export
function
getMemoResourceList
(
memoId
:
MemoId
)
{
return
axios
.
get
<
Resource
[]
>
(
`/api/v1/memo/
${
memoId
}
/resource`
);
}
export
function
upsertMemoResource
(
memoId
:
MemoId
,
resourceId
:
ResourceId
)
{
return
axios
.
post
(
`/api/v1/memo/
${
memoId
}
/resource`
,
{
resourceId
,
});
}
export
function
deleteMemoResource
(
memoId
:
MemoId
,
resourceId
:
ResourceId
)
{
return
axios
.
delete
(
`/api/v1/memo/
${
memoId
}
/resource/
${
resourceId
}
`
);
}
export
function
getTagList
()
{
export
function
getTagList
()
{
return
axios
.
get
<
string
[]
>
(
`/api/v1/tag`
);
return
axios
.
get
<
string
[]
>
(
`/api/v1/tag`
);
}
}
...
...
web/src/store/module/resource.ts
View file @
6007f48b
...
@@ -40,31 +40,14 @@ export const useResourceStore = () => {
...
@@ -40,31 +40,14 @@ export const useResourceStore = () => {
store
.
dispatch
(
setResources
([
resource
,
...
resourceList
]));
store
.
dispatch
(
setResources
([
resource
,
...
resourceList
]));
return
resource
;
return
resource
;
},
},
async
createResourcesWithBlob
(
files
:
FileList
):
Promise
<
Array
<
Resource
>>
{
let
newResourceList
:
Array
<
Resource
>
=
[];
for
(
const
file
of
files
)
{
const
{
name
:
filename
,
size
}
=
file
;
if
(
size
>
maxUploadSizeMiB
*
1024
*
1024
)
{
return
Promise
.
reject
(
t
(
"message.file-exceeds-upload-limit-of"
,
{
file
:
filename
,
size
:
maxUploadSizeMiB
}));
}
const
formData
=
new
FormData
();
formData
.
append
(
"file"
,
file
,
filename
);
const
{
data
:
resource
}
=
await
api
.
createResourceWithBlob
(
formData
);
newResourceList
=
[
resource
,
...
newResourceList
];
}
const
resourceList
=
state
.
resources
;
store
.
dispatch
(
setResources
([...
newResourceList
,
...
resourceList
]));
return
newResourceList
;
},
async
deleteResourceById
(
id
:
ResourceId
)
{
await
api
.
deleteResourceById
(
id
);
store
.
dispatch
(
deleteResource
(
id
));
},
async
patchResource
(
resourcePatch
:
ResourcePatch
):
Promise
<
Resource
>
{
async
patchResource
(
resourcePatch
:
ResourcePatch
):
Promise
<
Resource
>
{
const
{
data
:
resource
}
=
await
api
.
patchResource
(
resourcePatch
);
const
{
data
:
resource
}
=
await
api
.
patchResource
(
resourcePatch
);
store
.
dispatch
(
patchResource
(
resource
));
store
.
dispatch
(
patchResource
(
resource
));
return
resource
;
return
resource
;
},
},
async
deleteResourceById
(
id
:
ResourceId
)
{
await
api
.
deleteResourceById
(
id
);
store
.
dispatch
(
deleteResource
(
id
));
},
};
};
};
};
web/src/types/modules/resource.d.ts
View file @
6007f48b
...
@@ -9,6 +9,7 @@ interface ResourceCreate {
...
@@ -9,6 +9,7 @@ interface ResourceCreate {
interface
ResourcePatch
{
interface
ResourcePatch
{
id
:
ResourceId
;
id
:
ResourceId
;
filename
?:
string
;
filename
?:
string
;
memoId
?:
number
;
}
}
interface
ResourceFind
{
interface
ResourceFind
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment