diff --git a/internal/core/core.go b/internal/core/core.go index 10ae82bf..65305200 100644 --- a/internal/core/core.go +++ b/internal/core/core.go @@ -34,6 +34,7 @@ type DataService interface { DeletePost(post *model.Post) error LockPost(post *model.Post) error StickPost(post *model.Post) error + VisibilityPost(post *model.Post) error GetPostByID(id int64) (*model.Post, error) GetPosts(conditions *model.ConditionsT, offset, limit int) ([]*model.Post, error) MergePosts(posts []*model.Post) ([]*model.PostFormated, error) diff --git a/internal/dao/post.go b/internal/dao/post.go index 292e16f9..3d757746 100644 --- a/internal/dao/post.go +++ b/internal/dao/post.go @@ -39,6 +39,10 @@ func (d *dataServant) StickPost(post *model.Post) error { return nil } +func (d *dataServant) VisibilityPost(post *model.Post) error { + return post.Update(d.engine) +} + func (d *dataServant) GetPostByID(id int64) (*model.Post, error) { post := &model.Post{ Model: &model.Model{ diff --git a/internal/routers/api/post.go b/internal/routers/api/post.go index c1452b8f..d54cad02 100644 --- a/internal/routers/api/post.go +++ b/internal/routers/api/post.go @@ -288,6 +288,42 @@ func StickPost(c *gin.Context) { }) } +func VisibilityPost(c *gin.Context) { + param := service.PostVisibilityReq{} + response := app.NewResponse(c) + valid, errs := app.BindAndValid(c, ¶m) + if !valid { + logrus.Errorf("app.BindAndValid errs: %v", errs) + response.ToErrorResponse(errcode.InvalidParams.WithDetails(errs.Errors()...)) + return + } + + user, _ := c.Get("USER") + + // 获取Post + postFormated, err := service.GetPost(param.ID) + if err != nil { + logrus.Errorf("service.GetPost err: %v\n", err) + response.ToErrorResponse(errcode.GetPostFailed) + return + } + + if postFormated.UserID != user.(*model.User).ID && !user.(*model.User).IsAdmin { + response.ToErrorResponse(errcode.NoPermission) + return + } + err = service.VisibilityPost(param.ID, param.Visibility) + if err != nil { + logrus.Errorf("service.LockPost err: %v\n", err) + response.ToErrorResponse(errcode.LockPostFailed) + return + } + + response.ToResponse(gin.H{ + "visibility": param.Visibility, + }) +} + func GetPostTags(c *gin.Context) { param := service.PostTagsReq{} response := app.NewResponse(c) diff --git a/internal/routers/router.go b/internal/routers/router.go index 9465ba4b..309385e4 100644 --- a/internal/routers/router.go +++ b/internal/routers/router.go @@ -167,6 +167,9 @@ func NewRouter() *gin.Engine { // 置顶动态 privApi.POST("/post/stick", api.StickPost) + // 修改动态可见度 + privApi.POST("/post/visibility", api.VisibilityPost) + // 发布动态评论 privApi.POST("/post/comment", api.CreatePostComment) diff --git a/internal/service/post.go b/internal/service/post.go index daa858bb..a2b4f9ce 100644 --- a/internal/service/post.go +++ b/internal/service/post.go @@ -51,6 +51,11 @@ type PostStickReq struct { ID int64 `json:"id" binding:"required"` } +type PostVisibilityReq struct { + ID int64 `json:"id" binding:"required"` + Visibility model.PostVisibleT `json:"visibility"` +} + type PostStarReq struct { ID int64 `json:"id" binding:"required"` } @@ -214,6 +219,19 @@ func StickPost(id int64) error { return nil } +func VisibilityPost(id int64, visibility model.PostVisibleT) error { + post, _ := ds.GetPostByID(id) + + // 修改可见度 + post.Visibility = visibility + err := ds.VisibilityPost(post) + if err != nil { + return err + } + + return nil +} + func GetPostStar(postID, userID int64) (*model.PostStar, error) { return ds.GetUserPostStar(postID, userID) } diff --git a/web/src/api/post.ts b/web/src/api/post.ts index 7f2bc408..d562149d 100644 --- a/web/src/api/post.ts +++ b/web/src/api/post.ts @@ -108,6 +108,15 @@ export const stickPost = (data: NetParams.PostStickPost): Promise => { + return request({ + method: 'post', + url: '/v1/post/visibility', + data + }); +}; + /** 发布动态评论 */ export const createComment = (data: NetParams.PostCreateComment): Promise => { return request({ diff --git a/web/src/components/compose.vue b/web/src/components/compose.vue index 90961614..74811c15 100644 --- a/web/src/components/compose.vue +++ b/web/src/components/compose.vue @@ -297,7 +297,7 @@ const fileQueue = ref([]); const imageContents = ref([]); const videoContents = ref([]); const attachmentContents = ref([]); -const visitType = ref(0) +const visitType = ref<0 | 1 | 2>(0) const visibilities = [{value: 0, label: "公开"}, {value: 1, label: "私密"}, {value: 2, label: "好友可见"}] const uploadGateway = import.meta.env.VITE_HOST + '/v1/attachment'; diff --git a/web/src/components/post-detail.vue b/web/src/components/post-detail.vue index f937b10c..69e8216b 100644 --- a/web/src/components/post-detail.vue +++ b/web/src/components/post-detail.vue @@ -110,6 +110,21 @@ negative-text="取消" @positive-click="execStickAction" /> + +
(0); const emit = defineEmits<{ (e: 'reload'): void; @@ -265,7 +284,7 @@ const post = computed({ }); const adminOptions = computed(() => { - let options = [ + let options: DropdownOption[] = [ { label: '删除', key: 'delete', @@ -295,6 +314,34 @@ const adminOptions = computed(() => { }); } } + if (post.value.visibility === 0) { + options.push({ + label: '公开', + key: 'vpublic', + children: [ + { label: '私密', key: 'vprivate' } + , { label: '好友可见', key: 'vfriend' } + ] + }) + } else if (post.value.visibility === 1) { + options.push({ + label: '私密', + key: 'vprivate', + children: [ + { label: '公开', key: 'vpublic' } + , { label: '好友可见', key: 'vfriend' } + ] + }) + } else { + options.push({ + label: '好友可见', + key: 'vfriend', + children: [ + { label: '公开', key: 'vpublic' } + , { label: '私密', key: 'vprivate' } + ] + }) + } return options; }); @@ -333,16 +380,34 @@ const doClickText = (e: MouseEvent, id: number) => { goPostDetail(id); }; const handlePostAction = ( - item: 'delete' | 'lock' | 'unlock' | 'stick' | 'unstick' + item: 'delete' | 'lock' | 'unlock' | 'stick' | 'unstick' | 'vpublic' | 'vprivate' | 'vfriend' ) => { - if (item === 'delete') { - showDelModal.value = true; - } - if (item === 'lock' || item === 'unlock') { - showLockModal.value = true; - } - if (item === 'stick' || item === 'unstick') { - showStickModal.value = true; + switch (item) { + case 'delete': + showDelModal.value = true; + break; + case 'lock': + case 'unlock': + showLockModal.value = true; + break; + case 'stick': + case 'unstick': + showStickModal.value = true; + break; + case 'vpublic': + tempVisibility.value = 0; + showVisibilityModal.value = true; + break; + case 'vprivate': + tempVisibility.value = 1; + showVisibilityModal.value = true; + break; + case 'vfriend': + tempVisibility.value = 2; + showVisibilityModal.value = true; + break; + default: + break; } }; const execDelAction = () => { @@ -393,6 +458,19 @@ const execStickAction = () => { loading.value = false; }); }; +const execVisibilityAction = () => { + visibilityPost({ + id: post.value.id, + visibility: tempVisibility.value + }) + .then((res) => { + emit('reload'); + window.$message.success('修改可见性成功'); + }) + .catch((err) => { + loading.value = false; + }); +}; const handlePostStar = () => { postStar({ id: post.value.id, diff --git a/web/src/types/NetParams.d.ts b/web/src/types/NetParams.d.ts index 122e3189..b6371564 100644 --- a/web/src/types/NetParams.d.ts +++ b/web/src/types/NetParams.d.ts @@ -124,6 +124,12 @@ declare module NetParams { id: number } + interface PostVisibilityPost { + id: number, + /** 可见性 0公开 1私密 2好友可见 */ + visibility: 0 | 1 | 2 + } + interface PostGetPostStar { id: number } diff --git a/web/src/types/NetReq.d.ts b/web/src/types/NetReq.d.ts index 8c34f61e..ffc6c55d 100644 --- a/web/src/types/NetReq.d.ts +++ b/web/src/types/NetReq.d.ts @@ -116,6 +116,11 @@ declare module NetReq { top_status: 0 | 1 } + interface PostVisibilityPost { + /** 可见性 0公开 1私密 2好友可见 */ + visibility_status: 0 | 1 | 2 + } + interface PostGetPostStar { status: boolean }