feat: stick post for admin

pull/21/head
ROC 3 years ago
parent 2a9df4a522
commit 0587c3d6df

@ -20,6 +20,11 @@ func (d *Dao) LockPost(post *model.Post) error {
return post.Update(d.engine) return post.Update(d.engine)
} }
func (d *Dao) StickPost(post *model.Post) error {
post.IsTop = 1 - post.IsTop
return post.Update(d.engine)
}
func (d *Dao) GetPostByID(id int64) (*model.Post, error) { func (d *Dao) GetPostByID(id int64) (*model.Post, error) {
post := &model.Post{ post := &model.Post{
Model: &model.Model{ Model: &model.Model{

@ -266,6 +266,43 @@ func LockPost(c *gin.Context) {
}) })
} }
func StickPost(c *gin.Context) {
param := service.PostStickReq{}
response := app.NewResponse(c)
valid, errs := app.BindAndValid(c, &param)
if !valid {
global.Logger.Errorf("app.BindAndValid errs: %v", errs)
response.ToErrorResponse(errcode.InvalidParams.WithDetails(errs.Errors()...))
return
}
user, _ := c.Get("USER")
svc := service.New(c)
// 获取Post
postFormated, err := svc.GetPost(param.ID)
if err != nil {
global.Logger.Errorf("svc.GetPost err: %v\n", err)
response.ToErrorResponse(errcode.GetPostFailed)
return
}
if !user.(*model.User).IsAdmin {
response.ToErrorResponse(errcode.NoPermission)
return
}
err = svc.StickPost(param.ID)
if err != nil {
global.Logger.Errorf("svc.StickPost err: %v\n", err)
response.ToErrorResponse(errcode.LockPostFailed)
return
}
response.ToResponse(gin.H{
"top_status": 1 - postFormated.IsTop,
})
}
func GetPostTags(c *gin.Context) { func GetPostTags(c *gin.Context) {
param := service.PostTagsReq{} param := service.PostTagsReq{}
response := app.NewResponse(c) response := app.NewResponse(c)

@ -146,6 +146,9 @@ func NewRouter() *gin.Engine {
// 锁定动态 // 锁定动态
privApi.POST("/post/lock", api.LockPost) privApi.POST("/post/lock", api.LockPost)
// 置顶动态
privApi.POST("/post/stick", api.StickPost)
// 发布动态评论 // 发布动态评论
privApi.POST("/post/comment", api.CreatePostComment) privApi.POST("/post/comment", api.CreatePostComment)

@ -42,6 +42,9 @@ type PostDelReq struct {
type PostLockReq struct { type PostLockReq struct {
ID int64 `json:"id" binding:"required"` ID int64 `json:"id" binding:"required"`
} }
type PostStickReq struct {
ID int64 `json:"id" binding:"required"`
}
type PostStarReq struct { type PostStarReq struct {
ID int64 `json:"id" binding:"required"` ID int64 `json:"id" binding:"required"`
} }
@ -167,6 +170,18 @@ func (svc *Service) LockPost(id int64) error {
return nil return nil
} }
func (svc *Service) StickPost(id int64) error {
post, _ := svc.dao.GetPostByID(id)
err := svc.dao.StickPost(post)
if err != nil {
return err
}
return nil
}
func (svc *Service) GetPostStar(postID, userID int64) (*model.PostStar, error) { func (svc *Service) GetPostStar(postID, userID int64) (*model.PostStar, error) {
return svc.dao.GetUserPostStar(postID, userID) return svc.dao.GetUserPostStar(postID, userID)
} }

@ -33,6 +33,7 @@ var (
DownloadReqError = NewError(30008, "附件下载请求失败") DownloadReqError = NewError(30008, "附件下载请求失败")
InsuffientDownloadMoney = NewError(30009, "附件下载失败:账户资金不足") InsuffientDownloadMoney = NewError(30009, "附件下载失败:账户资金不足")
DownloadExecFail = NewError(30010, "附件下载失败:扣费失败") DownloadExecFail = NewError(30010, "附件下载失败:扣费失败")
StickPostFailed = NewError(30011, "动态置顶失败")
GetCommentsFailed = NewError(40001, "获取评论列表失败") GetCommentsFailed = NewError(40001, "获取评论列表失败")
CreateCommentFailed = NewError(40002, "评论发布失败") CreateCommentFailed = NewError(40002, "评论发布失败")

@ -148,6 +148,20 @@ export const lockPost = (data: NetParams.PostLockPost) => {
}) as unknown as Promise<NetReq.PostLockPost>; }) as unknown as Promise<NetReq.PostLockPost>;
}; };
/**
* /
* @param {Object} data
* - @param {number} id
* @returns Promise
*/
export const stickPost = (data: NetParams.PostStickPost) => {
return request({
method: 'post',
url: '/post/stick',
data
}) as unknown as Promise<NetReq.PostStickPost>;
};
/** /**
* *
* @param {Object} data * @param {Object} data

@ -59,11 +59,30 @@
:mask-closable="false" :mask-closable="false"
preset="dialog" preset="dialog"
title="提示" title="提示"
content="确定锁定该泡泡动态吗?" :content="
'' +
(post.is_lock ? '' : '') +
''
"
positive-text="确认" positive-text="确认"
negative-text="取消" negative-text="取消"
@positive-click="execLockAction" @positive-click="execLockAction"
/> />
<!-- -->
<n-modal
v-model:show="showStickModal"
:mask-closable="false"
preset="dialog"
title="提示"
:content="
'' +
(post.is_top ? '' : '') +
''
"
positive-text="确认"
negative-text="取消"
@positive-click="execStickAction"
/>
</template> </template>
<div v-if="post.texts.length > 0"> <div v-if="post.texts.length > 0">
<span <span
@ -154,21 +173,26 @@ import {
postCollection, postCollection,
deletePost, deletePost,
lockPost, lockPost,
stickPost,
} from '@/api/post'; } from '@/api/post';
const store = useStore(); const store = useStore();
const router = useRouter(); const router = useRouter();
const hasStarred = ref(false); const hasStarred = ref(false);
const hasCollected = ref(false); const hasCollected = ref(false);
const props = withDefaults(defineProps<{ const props = withDefaults(
post: Item.PostProps, defineProps<{
}>(), {}); post: Item.PostProps;
}>(),
{}
);
const showDelModal = ref(false); const showDelModal = ref(false);
const showLockModal = ref(false); const showLockModal = ref(false);
const showStickModal = ref(false);
const loading = ref(false); const loading = ref(false);
const emit = defineEmits<{ const emit = defineEmits<{
(e: "reload"): void (e: 'reload'): void;
}>(); }>();
const post = computed({ const post = computed({
@ -232,16 +256,17 @@ const adminOptions = computed(() => {
}); });
} }
if (store.state.userInfo.is_admin) { if (store.state.userInfo.is_admin) {
options.push( if (post.value.is_top === 0) {
{ options.push({
label: '', label: '',
key: 'top', key: 'stick',
}, });
{ } else {
label: '', options.push({
key: 'essence', label: '',
} key: 'unstick',
); });
}
} }
return options; return options;
}); });
@ -280,13 +305,18 @@ const doClickText = (e: MouseEvent, id: number) => {
} }
goPostDetail(id); goPostDetail(id);
}; };
const handlePostAction = (item: "delete" | "lock" | "unlock") => { const handlePostAction = (
item: 'delete' | 'lock' | 'unlock' | 'stick' | 'unstick'
) => {
if (item === 'delete') { if (item === 'delete') {
showDelModal.value = true; showDelModal.value = true;
} }
if (item === 'lock' || item === 'unlock') { if (item === 'lock' || item === 'unlock') {
showLockModal.value = true; showLockModal.value = true;
} }
if (item === 'stick' || item === 'unstick') {
showStickModal.value = true;
}
}; };
const execDelAction = () => { const execDelAction = () => {
deletePost({ deletePost({
@ -320,6 +350,22 @@ const execLockAction = () => {
loading.value = false; loading.value = false;
}); });
}; };
const execStickAction = () => {
stickPost({
id: post.value.id,
})
.then((res) => {
emit('reload');
if (res.top_status === 1) {
window.$message.success('');
} else {
window.$message.success('');
}
})
.catch((err) => {
loading.value = false;
});
};
const handlePostStar = () => { const handlePostStar = () => {
postStar({ postStar({
id: post.value.id, id: post.value.id,

@ -84,6 +84,10 @@ declare module NetParams {
id: number id: number
} }
interface PostStickPost {
id: number
}
interface PostGetPostStar { interface PostGetPostStar {
id: number id: number
} }

@ -17,7 +17,7 @@ declare module NetReq {
} }
type UserGetAttachment = string type UserGetAttachment = string
interface UserGetUnreadMsgCount { interface UserGetUnreadMsgCount {
count: number count: number
} }
@ -26,7 +26,7 @@ declare module NetReq {
list: Item.MessageProps[], list: Item.MessageProps[],
pager: Item.PagerProps pager: Item.PagerProps
} }
interface UserGetUserPosts { interface UserGetUserPosts {
list: Item.PostProps[], list: Item.PostProps[],
pager: Item.PagerProps pager: Item.PagerProps
@ -73,6 +73,10 @@ declare module NetReq {
lock_status: number lock_status: number
} }
interface PostStickPost {
top_status: number
}
interface PostGetPostStar { interface PostGetPostStar {
status: boolean status: boolean
} }

@ -46,7 +46,7 @@ declare module Item {
content: string, content: string,
contents: PostProps[], contents: PostProps[],
is_lock: number, is_lock: number,
is_top: boolean, is_top: number,
texts?: PostProps[], texts?: PostProps[],
imgs?: PostProps[], imgs?: PostProps[],
videos?: PostProps[], videos?: PostProps[],

Loading…
Cancel
Save