|
|
|
|
@ -216,49 +216,50 @@
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { h, ref, onMounted, computed } from 'vue';
|
|
|
|
|
import type { Component } from 'vue'
|
|
|
|
|
import { NIcon, useDialog } from 'naive-ui'
|
|
|
|
|
import type { Component } from 'vue';
|
|
|
|
|
import { NIcon, useDialog } from 'naive-ui';
|
|
|
|
|
import { useStore } from 'vuex';
|
|
|
|
|
import { useRouter } from 'vue-router';
|
|
|
|
|
import { formatPrettyTime } from '@/utils/formatTime';
|
|
|
|
|
import { parsePostTag } from '@/utils/content';
|
|
|
|
|
import {
|
|
|
|
|
PaperPlaneOutline,
|
|
|
|
|
Heart,
|
|
|
|
|
HeartOutline,
|
|
|
|
|
Bookmark,
|
|
|
|
|
BookmarkOutline,
|
|
|
|
|
ShareSocialOutline,
|
|
|
|
|
ChatboxOutline,
|
|
|
|
|
PushOutline,
|
|
|
|
|
TrashOutline,
|
|
|
|
|
LockClosedOutline,
|
|
|
|
|
LockOpenOutline,
|
|
|
|
|
EyeOutline,
|
|
|
|
|
EyeOffOutline,
|
|
|
|
|
BodyOutline,
|
|
|
|
|
WalkOutline,
|
|
|
|
|
PersonOutline,
|
|
|
|
|
FlameOutline,
|
|
|
|
|
PaperPlaneOutline,
|
|
|
|
|
Heart,
|
|
|
|
|
HeartOutline,
|
|
|
|
|
Bookmark,
|
|
|
|
|
BookmarkOutline,
|
|
|
|
|
ShareSocialOutline,
|
|
|
|
|
ChatboxOutline,
|
|
|
|
|
PushOutline,
|
|
|
|
|
TrashOutline,
|
|
|
|
|
LockClosedOutline,
|
|
|
|
|
LockOpenOutline,
|
|
|
|
|
EyeOutline,
|
|
|
|
|
EyeOffOutline,
|
|
|
|
|
BodyOutline,
|
|
|
|
|
WalkOutline,
|
|
|
|
|
PersonOutline,
|
|
|
|
|
FlameOutline,
|
|
|
|
|
} from '@vicons/ionicons5';
|
|
|
|
|
import { MoreHorizFilled } from '@vicons/material';
|
|
|
|
|
import {
|
|
|
|
|
getPostStar,
|
|
|
|
|
postStar,
|
|
|
|
|
getPostCollection,
|
|
|
|
|
postCollection,
|
|
|
|
|
deletePost,
|
|
|
|
|
lockPost,
|
|
|
|
|
stickPost,
|
|
|
|
|
highlightPost,
|
|
|
|
|
visibilityPost
|
|
|
|
|
getPostStar,
|
|
|
|
|
postStar,
|
|
|
|
|
getPostCollection,
|
|
|
|
|
postCollection,
|
|
|
|
|
deletePost,
|
|
|
|
|
lockPost,
|
|
|
|
|
stickPost,
|
|
|
|
|
highlightPost,
|
|
|
|
|
visibilityPost,
|
|
|
|
|
} from '@/api/post';
|
|
|
|
|
import { followUser, unfollowUser } from '@/api/user';
|
|
|
|
|
import type { DropdownOption } from 'naive-ui';
|
|
|
|
|
import { VisibilityEnum } from '@/utils/IEnum';
|
|
|
|
|
import copy from "copy-to-clipboard";
|
|
|
|
|
import copy from 'copy-to-clipboard';
|
|
|
|
|
|
|
|
|
|
const useFriendship = (import.meta.env.VITE_USE_FRIENDSHIP.toLowerCase() === 'true')
|
|
|
|
|
const useFriendship =
|
|
|
|
|
import.meta.env.VITE_USE_FRIENDSHIP.toLowerCase() === 'true';
|
|
|
|
|
|
|
|
|
|
const store = useStore();
|
|
|
|
|
const router = useRouter();
|
|
|
|
|
@ -266,10 +267,10 @@ const dialog = useDialog();
|
|
|
|
|
const hasStarred = ref(false);
|
|
|
|
|
const hasCollected = ref(false);
|
|
|
|
|
const props = withDefaults(
|
|
|
|
|
defineProps<{
|
|
|
|
|
post: Item.PostProps;
|
|
|
|
|
}>(),
|
|
|
|
|
{}
|
|
|
|
|
defineProps<{
|
|
|
|
|
post: Item.PostProps;
|
|
|
|
|
}>(),
|
|
|
|
|
{},
|
|
|
|
|
);
|
|
|
|
|
const showDelModal = ref(false);
|
|
|
|
|
const showLockModal = ref(false);
|
|
|
|
|
@ -280,462 +281,490 @@ const loading = ref(false);
|
|
|
|
|
const tempVisibility = ref<VisibilityEnum>(VisibilityEnum.PUBLIC);
|
|
|
|
|
const showWhisper = ref(false);
|
|
|
|
|
const whisperReceiver = ref<Item.UserInfo>({
|
|
|
|
|
id: 0,
|
|
|
|
|
avatar: '',
|
|
|
|
|
username: '',
|
|
|
|
|
nickname: '',
|
|
|
|
|
is_admin: false,
|
|
|
|
|
is_friend: true,
|
|
|
|
|
is_following: false,
|
|
|
|
|
created_on: 0,
|
|
|
|
|
follows: 0,
|
|
|
|
|
followings: 0,
|
|
|
|
|
status: 1,
|
|
|
|
|
id: 0,
|
|
|
|
|
avatar: '',
|
|
|
|
|
username: '',
|
|
|
|
|
nickname: '',
|
|
|
|
|
is_admin: false,
|
|
|
|
|
is_friend: true,
|
|
|
|
|
is_following: false,
|
|
|
|
|
created_on: 0,
|
|
|
|
|
follows: 0,
|
|
|
|
|
followings: 0,
|
|
|
|
|
status: 1,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const onSendWhisper = (user: Item.UserInfo) => {
|
|
|
|
|
whisperReceiver.value = user;
|
|
|
|
|
showWhisper.value = true;
|
|
|
|
|
const onSendWhisper = (user: Item.UserInfo) => {
|
|
|
|
|
whisperReceiver.value = user;
|
|
|
|
|
showWhisper.value = true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const whisperSuccess = () => {
|
|
|
|
|
showWhisper.value = false;
|
|
|
|
|
showWhisper.value = false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const emit = defineEmits<{
|
|
|
|
|
(e: 'reload', post_id: number): void;
|
|
|
|
|
(e: 'reload', post_id: number): void;
|
|
|
|
|
}>();
|
|
|
|
|
|
|
|
|
|
const post = computed({
|
|
|
|
|
get: () => {
|
|
|
|
|
let post: Item.PostComponentProps = Object.assign(
|
|
|
|
|
{
|
|
|
|
|
texts: [],
|
|
|
|
|
imgs: [],
|
|
|
|
|
videos: [],
|
|
|
|
|
links: [],
|
|
|
|
|
attachments: [],
|
|
|
|
|
charge_attachments: [],
|
|
|
|
|
},
|
|
|
|
|
props.post
|
|
|
|
|
);
|
|
|
|
|
post.contents.map((content) => {
|
|
|
|
|
if (+content.type === 1 || +content.type === 2) {
|
|
|
|
|
post.texts.push(content);
|
|
|
|
|
}
|
|
|
|
|
if (+content.type === 3) {
|
|
|
|
|
post.imgs.push(content);
|
|
|
|
|
}
|
|
|
|
|
if (+content.type === 4) {
|
|
|
|
|
post.videos.push(content);
|
|
|
|
|
}
|
|
|
|
|
if (+content.type === 6) {
|
|
|
|
|
post.links.push(content);
|
|
|
|
|
}
|
|
|
|
|
if (+content.type === 7) {
|
|
|
|
|
post.attachments.push(content);
|
|
|
|
|
}
|
|
|
|
|
if (+content.type === 8) {
|
|
|
|
|
post.charge_attachments.push(content);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return post;
|
|
|
|
|
},
|
|
|
|
|
set: (newVal) => {
|
|
|
|
|
props.post.upvote_count = newVal.upvote_count;
|
|
|
|
|
props.post.comment_count = newVal.comment_count;
|
|
|
|
|
props.post.collection_count = newVal.collection_count;
|
|
|
|
|
props.post.is_essence = newVal.is_essence;
|
|
|
|
|
},
|
|
|
|
|
get: () => {
|
|
|
|
|
let post: Item.PostComponentProps = Object.assign(
|
|
|
|
|
{
|
|
|
|
|
texts: [],
|
|
|
|
|
imgs: [],
|
|
|
|
|
videos: [],
|
|
|
|
|
links: [],
|
|
|
|
|
attachments: [],
|
|
|
|
|
charge_attachments: [],
|
|
|
|
|
},
|
|
|
|
|
props.post,
|
|
|
|
|
);
|
|
|
|
|
post.contents.map((content) => {
|
|
|
|
|
if (+content.type === 1 || +content.type === 2) {
|
|
|
|
|
post.texts.push(content);
|
|
|
|
|
}
|
|
|
|
|
if (+content.type === 3) {
|
|
|
|
|
post.imgs.push(content);
|
|
|
|
|
}
|
|
|
|
|
if (+content.type === 4) {
|
|
|
|
|
post.videos.push(content);
|
|
|
|
|
}
|
|
|
|
|
if (+content.type === 6) {
|
|
|
|
|
post.links.push(content);
|
|
|
|
|
}
|
|
|
|
|
if (+content.type === 7) {
|
|
|
|
|
post.attachments.push(content);
|
|
|
|
|
}
|
|
|
|
|
if (+content.type === 8) {
|
|
|
|
|
post.charge_attachments.push(content);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return post;
|
|
|
|
|
},
|
|
|
|
|
set: (newVal) => {
|
|
|
|
|
props.post.upvote_count = newVal.upvote_count;
|
|
|
|
|
props.post.comment_count = newVal.comment_count;
|
|
|
|
|
props.post.collection_count = newVal.collection_count;
|
|
|
|
|
props.post.is_essence = newVal.is_essence;
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const renderIcon = (icon: Component) => {
|
|
|
|
|
return () => {
|
|
|
|
|
return h(NIcon, null, {
|
|
|
|
|
default: () => h(icon)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
default: () => h(icon),
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const adminOptions = computed(() => {
|
|
|
|
|
let options: DropdownOption[] = [];
|
|
|
|
|
if (!store.state.userInfo.is_admin && store.state.userInfo.id != props.post.user.id) {
|
|
|
|
|
options.push({
|
|
|
|
|
label: '私信 @' + props.post.user.username,
|
|
|
|
|
key: 'whisper',
|
|
|
|
|
icon: renderIcon(PaperPlaneOutline)
|
|
|
|
|
});
|
|
|
|
|
if (props.post.user.is_following) {
|
|
|
|
|
options.push({
|
|
|
|
|
label: '取消关注 @' + props.post.user.username,
|
|
|
|
|
key: 'unfollow',
|
|
|
|
|
icon: renderIcon(WalkOutline)
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
options.push({
|
|
|
|
|
label: '关注 @' + props.post.user.username,
|
|
|
|
|
key: 'follow',
|
|
|
|
|
icon: renderIcon(BodyOutline)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
return options;
|
|
|
|
|
}
|
|
|
|
|
let options: DropdownOption[] = [];
|
|
|
|
|
if (
|
|
|
|
|
!store.state.userInfo.is_admin &&
|
|
|
|
|
store.state.userInfo.id != props.post.user.id
|
|
|
|
|
) {
|
|
|
|
|
options.push({
|
|
|
|
|
label: '删除',
|
|
|
|
|
key: 'delete',
|
|
|
|
|
icon: renderIcon(TrashOutline)
|
|
|
|
|
})
|
|
|
|
|
if (post.value.is_lock === 0) {
|
|
|
|
|
options.push({
|
|
|
|
|
label: '锁定',
|
|
|
|
|
key: 'lock',
|
|
|
|
|
icon: renderIcon(LockClosedOutline)
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
options.push({
|
|
|
|
|
label: '解锁',
|
|
|
|
|
key: 'unlock',
|
|
|
|
|
icon: renderIcon(LockOpenOutline)
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (store.state.userInfo.is_admin) {
|
|
|
|
|
if (post.value.is_top === 0) {
|
|
|
|
|
options.push({
|
|
|
|
|
label: '置顶',
|
|
|
|
|
key: 'stick',
|
|
|
|
|
icon: renderIcon(PushOutline)
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
options.push({
|
|
|
|
|
label: '取消置顶',
|
|
|
|
|
key: 'unstick',
|
|
|
|
|
icon: renderIcon(PushOutline)
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (post.value.is_essence === 0) {
|
|
|
|
|
options.push({
|
|
|
|
|
label: '设为亮点',
|
|
|
|
|
key: 'highlight',
|
|
|
|
|
icon: renderIcon(FlameOutline)
|
|
|
|
|
});
|
|
|
|
|
label: '私信 @' + props.post.user.username,
|
|
|
|
|
key: 'whisper',
|
|
|
|
|
icon: renderIcon(PaperPlaneOutline),
|
|
|
|
|
});
|
|
|
|
|
if (props.post.user.is_following) {
|
|
|
|
|
options.push({
|
|
|
|
|
label: '取消关注 @' + props.post.user.username,
|
|
|
|
|
key: 'unfollow',
|
|
|
|
|
icon: renderIcon(WalkOutline),
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
options.push({
|
|
|
|
|
label: '取消亮点',
|
|
|
|
|
key: 'unhighlight',
|
|
|
|
|
icon: renderIcon(FlameOutline)
|
|
|
|
|
});
|
|
|
|
|
options.push({
|
|
|
|
|
label: '关注 @' + props.post.user.username,
|
|
|
|
|
key: 'follow',
|
|
|
|
|
icon: renderIcon(BodyOutline),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
let visitMenu: DropdownOption
|
|
|
|
|
if (post.value.visibility === VisibilityEnum.PUBLIC) {
|
|
|
|
|
visitMenu = {
|
|
|
|
|
label: '公开',
|
|
|
|
|
key: 'vpublic',
|
|
|
|
|
icon: renderIcon(EyeOutline),
|
|
|
|
|
children: [
|
|
|
|
|
{ label: '私密', key: 'vprivate', icon: renderIcon(EyeOffOutline) },
|
|
|
|
|
{ label: '关注可见', key: 'vfollowing', icon: renderIcon(BodyOutline) }
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
} else if (post.value.visibility === VisibilityEnum.PRIVATE) {
|
|
|
|
|
visitMenu = {
|
|
|
|
|
label: '私密',
|
|
|
|
|
key: 'vprivate',
|
|
|
|
|
icon: renderIcon(EyeOffOutline),
|
|
|
|
|
children: [
|
|
|
|
|
{ label: '公开', key: 'vpublic', icon: renderIcon(EyeOutline) },
|
|
|
|
|
{ label: '关注可见', key: 'vfollowing', icon: renderIcon(BodyOutline) }
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
} else if (useFriendship && post.value.visibility === VisibilityEnum.FRIEND) {
|
|
|
|
|
visitMenu = {
|
|
|
|
|
label: '好友可见',
|
|
|
|
|
key: 'vfriend',
|
|
|
|
|
icon: renderIcon(PersonOutline),
|
|
|
|
|
children: [
|
|
|
|
|
{ label: '公开', key: 'vpublic', icon: renderIcon(EyeOutline) },
|
|
|
|
|
{ label: '私密', key: 'vprivate', icon: renderIcon(EyeOffOutline) },
|
|
|
|
|
{ label: '关注可见', key: 'vfollowing', icon: renderIcon(BodyOutline) }
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
return options;
|
|
|
|
|
}
|
|
|
|
|
options.push({
|
|
|
|
|
label: '删除',
|
|
|
|
|
key: 'delete',
|
|
|
|
|
icon: renderIcon(TrashOutline),
|
|
|
|
|
});
|
|
|
|
|
if (post.value.is_lock === 0) {
|
|
|
|
|
options.push({
|
|
|
|
|
label: '锁定',
|
|
|
|
|
key: 'lock',
|
|
|
|
|
icon: renderIcon(LockClosedOutline),
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
options.push({
|
|
|
|
|
label: '解锁',
|
|
|
|
|
key: 'unlock',
|
|
|
|
|
icon: renderIcon(LockOpenOutline),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (store.state.userInfo.is_admin) {
|
|
|
|
|
if (post.value.is_top === 0) {
|
|
|
|
|
options.push({
|
|
|
|
|
label: '置顶',
|
|
|
|
|
key: 'stick',
|
|
|
|
|
icon: renderIcon(PushOutline),
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
visitMenu = {
|
|
|
|
|
label: '关注可见',
|
|
|
|
|
key: 'vfollowing',
|
|
|
|
|
icon: renderIcon(BodyOutline),
|
|
|
|
|
children: [
|
|
|
|
|
{ label: '公开', key: 'vpublic', icon: renderIcon(EyeOutline) },
|
|
|
|
|
{ label: '私密', key: 'vprivate', icon: renderIcon(EyeOffOutline) }
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
if (useFriendship && post.value.visibility !== VisibilityEnum.FRIEND) {
|
|
|
|
|
visitMenu.children?.push({ label: '好友可见', key: 'vfriend', icon: renderIcon(PersonOutline) })
|
|
|
|
|
options.push({
|
|
|
|
|
label: '取消置顶',
|
|
|
|
|
key: 'unstick',
|
|
|
|
|
icon: renderIcon(PushOutline),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
options.push(visitMenu);
|
|
|
|
|
return options;
|
|
|
|
|
}
|
|
|
|
|
if (post.value.is_essence === 0) {
|
|
|
|
|
options.push({
|
|
|
|
|
label: '设为亮点',
|
|
|
|
|
key: 'highlight',
|
|
|
|
|
icon: renderIcon(FlameOutline),
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
options.push({
|
|
|
|
|
label: '取消亮点',
|
|
|
|
|
key: 'unhighlight',
|
|
|
|
|
icon: renderIcon(FlameOutline),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
let visitMenu: DropdownOption;
|
|
|
|
|
if (post.value.visibility === VisibilityEnum.PUBLIC) {
|
|
|
|
|
visitMenu = {
|
|
|
|
|
label: '公开',
|
|
|
|
|
key: 'vpublic',
|
|
|
|
|
icon: renderIcon(EyeOutline),
|
|
|
|
|
children: [
|
|
|
|
|
{ label: '私密', key: 'vprivate', icon: renderIcon(EyeOffOutline) },
|
|
|
|
|
{ label: '关注可见', key: 'vfollowing', icon: renderIcon(BodyOutline) },
|
|
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
} else if (post.value.visibility === VisibilityEnum.PRIVATE) {
|
|
|
|
|
visitMenu = {
|
|
|
|
|
label: '私密',
|
|
|
|
|
key: 'vprivate',
|
|
|
|
|
icon: renderIcon(EyeOffOutline),
|
|
|
|
|
children: [
|
|
|
|
|
{ label: '公开', key: 'vpublic', icon: renderIcon(EyeOutline) },
|
|
|
|
|
{ label: '关注可见', key: 'vfollowing', icon: renderIcon(BodyOutline) },
|
|
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
} else if (useFriendship && post.value.visibility === VisibilityEnum.FRIEND) {
|
|
|
|
|
visitMenu = {
|
|
|
|
|
label: '好友可见',
|
|
|
|
|
key: 'vfriend',
|
|
|
|
|
icon: renderIcon(PersonOutline),
|
|
|
|
|
children: [
|
|
|
|
|
{ label: '公开', key: 'vpublic', icon: renderIcon(EyeOutline) },
|
|
|
|
|
{ label: '私密', key: 'vprivate', icon: renderIcon(EyeOffOutline) },
|
|
|
|
|
{ label: '关注可见', key: 'vfollowing', icon: renderIcon(BodyOutline) },
|
|
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
visitMenu = {
|
|
|
|
|
label: '关注可见',
|
|
|
|
|
key: 'vfollowing',
|
|
|
|
|
icon: renderIcon(BodyOutline),
|
|
|
|
|
children: [
|
|
|
|
|
{ label: '公开', key: 'vpublic', icon: renderIcon(EyeOutline) },
|
|
|
|
|
{ label: '私密', key: 'vprivate', icon: renderIcon(EyeOffOutline) },
|
|
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
if (useFriendship && post.value.visibility !== VisibilityEnum.FRIEND) {
|
|
|
|
|
visitMenu.children?.push({
|
|
|
|
|
label: '好友可见',
|
|
|
|
|
key: 'vfriend',
|
|
|
|
|
icon: renderIcon(PersonOutline),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
options.push(visitMenu);
|
|
|
|
|
return options;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const onHandleFollowAction = (post: Item.PostProps) => {
|
|
|
|
|
dialog.success({
|
|
|
|
|
title: '提示',
|
|
|
|
|
content:
|
|
|
|
|
'确定' + (post.user.is_following ? '取消关注 @' : '关注 @') + props.post.user.username + ' 吗?',
|
|
|
|
|
positiveText: '确定',
|
|
|
|
|
negativeText: '取消',
|
|
|
|
|
onPositiveClick: () => {
|
|
|
|
|
if (post.user.is_following) {
|
|
|
|
|
unfollowUser({
|
|
|
|
|
user_id: post.user.id,
|
|
|
|
|
}).then((_res) => {
|
|
|
|
|
window.$message.success('操作成功');
|
|
|
|
|
post.user.is_following = false;
|
|
|
|
|
})
|
|
|
|
|
.catch((_err) => {});
|
|
|
|
|
} else {
|
|
|
|
|
followUser({
|
|
|
|
|
user_id: post.user.id,
|
|
|
|
|
}).then((_res) => {
|
|
|
|
|
window.$message.success('操作成功');
|
|
|
|
|
post.user.is_following = true;
|
|
|
|
|
})
|
|
|
|
|
.catch((_err) => {});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
dialog.success({
|
|
|
|
|
title: '提示',
|
|
|
|
|
content:
|
|
|
|
|
'确定' +
|
|
|
|
|
(post.user.is_following ? '取消关注 @' : '关注 @') +
|
|
|
|
|
props.post.user.username +
|
|
|
|
|
' 吗?',
|
|
|
|
|
positiveText: '确定',
|
|
|
|
|
negativeText: '取消',
|
|
|
|
|
onPositiveClick: () => {
|
|
|
|
|
if (post.user.is_following) {
|
|
|
|
|
unfollowUser({
|
|
|
|
|
user_id: post.user.id,
|
|
|
|
|
})
|
|
|
|
|
.then((_res) => {
|
|
|
|
|
window.$message.success('操作成功');
|
|
|
|
|
post.user.is_following = false;
|
|
|
|
|
})
|
|
|
|
|
.catch((_err) => {});
|
|
|
|
|
} else {
|
|
|
|
|
followUser({
|
|
|
|
|
user_id: post.user.id,
|
|
|
|
|
})
|
|
|
|
|
.then((_res) => {
|
|
|
|
|
window.$message.success('操作成功');
|
|
|
|
|
post.user.is_following = true;
|
|
|
|
|
})
|
|
|
|
|
.catch((_err) => {});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const goPostDetail = (id: number) => {
|
|
|
|
|
router.push({
|
|
|
|
|
name: 'post',
|
|
|
|
|
query: {
|
|
|
|
|
id,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
router.push({
|
|
|
|
|
name: 'post',
|
|
|
|
|
query: {
|
|
|
|
|
id,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
const doClickText = (e: MouseEvent, id: number) => {
|
|
|
|
|
if ((e.target as any).dataset.detail) {
|
|
|
|
|
const d = (e.target as any).dataset.detail.split(':');
|
|
|
|
|
if (d.length === 2) {
|
|
|
|
|
store.commit('refresh');
|
|
|
|
|
if (d[0] === 'tag') {
|
|
|
|
|
router.push({
|
|
|
|
|
name: 'home',
|
|
|
|
|
query: {
|
|
|
|
|
q: d[1],
|
|
|
|
|
t: 'tag',
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
router.push({
|
|
|
|
|
name: 'user',
|
|
|
|
|
query: {
|
|
|
|
|
s: d[1],
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if ((e.target as any).dataset.detail) {
|
|
|
|
|
const d = (e.target as any).dataset.detail.split(':');
|
|
|
|
|
if (d.length === 2) {
|
|
|
|
|
store.commit('refresh');
|
|
|
|
|
if (d[0] === 'tag') {
|
|
|
|
|
router.push({
|
|
|
|
|
name: 'home',
|
|
|
|
|
query: {
|
|
|
|
|
q: d[1],
|
|
|
|
|
t: 'tag',
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
router.push({
|
|
|
|
|
name: 'user',
|
|
|
|
|
query: {
|
|
|
|
|
s: d[1],
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
goPostDetail(id);
|
|
|
|
|
}
|
|
|
|
|
goPostDetail(id);
|
|
|
|
|
};
|
|
|
|
|
const handlePostAction = (
|
|
|
|
|
item: 'whisper' | 'follow' | 'unfollow' | 'delete' | 'lock' | 'unlock' | 'stick' | 'unstick' | 'highlight' | 'unhighlight' | 'vpublic' | 'vprivate' | 'vfriend' | 'vfollowing'
|
|
|
|
|
item:
|
|
|
|
|
| 'whisper'
|
|
|
|
|
| 'follow'
|
|
|
|
|
| 'unfollow'
|
|
|
|
|
| 'delete'
|
|
|
|
|
| 'lock'
|
|
|
|
|
| 'unlock'
|
|
|
|
|
| 'stick'
|
|
|
|
|
| 'unstick'
|
|
|
|
|
| 'highlight'
|
|
|
|
|
| 'unhighlight'
|
|
|
|
|
| 'vpublic'
|
|
|
|
|
| 'vprivate'
|
|
|
|
|
| 'vfriend'
|
|
|
|
|
| 'vfollowing',
|
|
|
|
|
) => {
|
|
|
|
|
switch (item) {
|
|
|
|
|
case 'whisper':
|
|
|
|
|
onSendWhisper(props.post.user);
|
|
|
|
|
break;
|
|
|
|
|
case 'follow':
|
|
|
|
|
case 'unfollow':
|
|
|
|
|
onHandleFollowAction(props.post);
|
|
|
|
|
break;
|
|
|
|
|
case 'delete':
|
|
|
|
|
showDelModal.value = true;
|
|
|
|
|
break;
|
|
|
|
|
case 'lock':
|
|
|
|
|
case 'unlock':
|
|
|
|
|
showLockModal.value = true;
|
|
|
|
|
break;
|
|
|
|
|
case 'stick':
|
|
|
|
|
case 'unstick':
|
|
|
|
|
showStickModal.value = true;
|
|
|
|
|
break;
|
|
|
|
|
case 'highlight':
|
|
|
|
|
case 'unhighlight':
|
|
|
|
|
showHighlightModal.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;
|
|
|
|
|
case 'vfollowing':
|
|
|
|
|
tempVisibility.value = 3;
|
|
|
|
|
showVisibilityModal.value = true;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
switch (item) {
|
|
|
|
|
case 'whisper':
|
|
|
|
|
onSendWhisper(props.post.user);
|
|
|
|
|
break;
|
|
|
|
|
case 'follow':
|
|
|
|
|
case 'unfollow':
|
|
|
|
|
onHandleFollowAction(props.post);
|
|
|
|
|
break;
|
|
|
|
|
case 'delete':
|
|
|
|
|
showDelModal.value = true;
|
|
|
|
|
break;
|
|
|
|
|
case 'lock':
|
|
|
|
|
case 'unlock':
|
|
|
|
|
showLockModal.value = true;
|
|
|
|
|
break;
|
|
|
|
|
case 'stick':
|
|
|
|
|
case 'unstick':
|
|
|
|
|
showStickModal.value = true;
|
|
|
|
|
break;
|
|
|
|
|
case 'highlight':
|
|
|
|
|
case 'unhighlight':
|
|
|
|
|
showHighlightModal.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;
|
|
|
|
|
case 'vfollowing':
|
|
|
|
|
tempVisibility.value = 3;
|
|
|
|
|
showVisibilityModal.value = true;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const execDelAction = () => {
|
|
|
|
|
deletePost({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
})
|
|
|
|
|
.then((_res) => {
|
|
|
|
|
window.$message.success('删除成功');
|
|
|
|
|
router.replace('/');
|
|
|
|
|
deletePost({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
})
|
|
|
|
|
.then((_res) => {
|
|
|
|
|
window.$message.success('删除成功');
|
|
|
|
|
router.replace('/');
|
|
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
store.commit('refresh');
|
|
|
|
|
}, 50);
|
|
|
|
|
})
|
|
|
|
|
.catch((_err) => {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
});
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
store.commit('refresh');
|
|
|
|
|
}, 50);
|
|
|
|
|
})
|
|
|
|
|
.catch((_err) => {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
const execLockAction = () => {
|
|
|
|
|
lockPost({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
lockPost({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
emit('reload', post.value.id);
|
|
|
|
|
if (res.lock_status === 1) {
|
|
|
|
|
window.$message.success('锁定成功');
|
|
|
|
|
} else {
|
|
|
|
|
window.$message.success('解锁成功');
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
emit('reload', post.value.id);
|
|
|
|
|
if (res.lock_status === 1) {
|
|
|
|
|
window.$message.success('锁定成功');
|
|
|
|
|
} else {
|
|
|
|
|
window.$message.success('解锁成功');
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((_err) => {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
});
|
|
|
|
|
.catch((_err) => {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
const execStickAction = () => {
|
|
|
|
|
stickPost({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
stickPost({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
emit('reload', post.value.id);
|
|
|
|
|
if (res.top_status === 1) {
|
|
|
|
|
window.$message.success('置顶成功');
|
|
|
|
|
} else {
|
|
|
|
|
window.$message.success('取消置顶成功');
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
emit('reload', post.value.id);
|
|
|
|
|
if (res.top_status === 1) {
|
|
|
|
|
window.$message.success('置顶成功');
|
|
|
|
|
} else {
|
|
|
|
|
window.$message.success('取消置顶成功');
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((_err) => {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
});
|
|
|
|
|
.catch((_err) => {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
const execHighlightAction = () => {
|
|
|
|
|
highlightPost({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
highlightPost({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
post.value = {
|
|
|
|
|
...post.value,
|
|
|
|
|
is_essence: res.highlight_status,
|
|
|
|
|
};
|
|
|
|
|
if (res.highlight_status === 1) {
|
|
|
|
|
window.$message.success('设为亮点成功');
|
|
|
|
|
} else {
|
|
|
|
|
window.$message.success('取消亮点成功');
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
post.value = {
|
|
|
|
|
...post.value,
|
|
|
|
|
is_essence: res.highlight_status,
|
|
|
|
|
};
|
|
|
|
|
if (res.highlight_status === 1) {
|
|
|
|
|
window.$message.success('设为亮点成功');
|
|
|
|
|
} else {
|
|
|
|
|
window.$message.success('取消亮点成功');
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((_err) => {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
});
|
|
|
|
|
.catch((_err) => {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
const execVisibilityAction = () => {
|
|
|
|
|
visibilityPost({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
visibility: tempVisibility.value
|
|
|
|
|
visibilityPost({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
visibility: tempVisibility.value,
|
|
|
|
|
})
|
|
|
|
|
.then((_res) => {
|
|
|
|
|
emit('reload', post.value.id);
|
|
|
|
|
window.$message.success('修改可见性成功');
|
|
|
|
|
})
|
|
|
|
|
.then((_res) => {
|
|
|
|
|
emit('reload', post.value.id);
|
|
|
|
|
window.$message.success('修改可见性成功');
|
|
|
|
|
})
|
|
|
|
|
.catch((_err) => {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
});
|
|
|
|
|
.catch((_err) => {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
const handlePostStar = () => {
|
|
|
|
|
postStar({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
postStar({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
hasStarred.value = res.status;
|
|
|
|
|
if (res.status) {
|
|
|
|
|
post.value = {
|
|
|
|
|
...post.value,
|
|
|
|
|
upvote_count: post.value.upvote_count + 1,
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
post.value = {
|
|
|
|
|
...post.value,
|
|
|
|
|
upvote_count: post.value.upvote_count - 1,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
hasStarred.value = res.status;
|
|
|
|
|
if (res.status) {
|
|
|
|
|
post.value = {
|
|
|
|
|
...post.value,
|
|
|
|
|
upvote_count: post.value.upvote_count + 1,
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
post.value = {
|
|
|
|
|
...post.value,
|
|
|
|
|
upvote_count: post.value.upvote_count - 1,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((err) => {
|
|
|
|
|
console.log(err);
|
|
|
|
|
});
|
|
|
|
|
.catch((err) => {
|
|
|
|
|
console.log(err);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
const handlePostCollection = () => {
|
|
|
|
|
postCollection({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
postCollection({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
hasCollected.value = res.status;
|
|
|
|
|
if (res.status) {
|
|
|
|
|
post.value = {
|
|
|
|
|
...post.value,
|
|
|
|
|
collection_count: post.value.collection_count + 1,
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
post.value = {
|
|
|
|
|
...post.value,
|
|
|
|
|
collection_count: post.value.collection_count - 1,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
hasCollected.value = res.status;
|
|
|
|
|
if (res.status) {
|
|
|
|
|
post.value = {
|
|
|
|
|
...post.value,
|
|
|
|
|
collection_count: post.value.collection_count + 1,
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
post.value = {
|
|
|
|
|
...post.value,
|
|
|
|
|
collection_count: post.value.collection_count - 1,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((err) => {
|
|
|
|
|
console.log(err);
|
|
|
|
|
});
|
|
|
|
|
.catch((err) => {
|
|
|
|
|
console.log(err);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
const handlePostShare = () => {
|
|
|
|
|
copy(`${window.location.origin}/#/post?id=${post.value.id}&share=copy_link&t=${new Date().getTime()}`);
|
|
|
|
|
window.$message.success('链接已复制到剪贴板');
|
|
|
|
|
copy(
|
|
|
|
|
`${window.location.origin}/#/post?id=${post.value.id}&share=copy_link&t=${new Date().getTime()}`,
|
|
|
|
|
);
|
|
|
|
|
window.$message.success('链接已复制到剪贴板');
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
if (store.state.userInfo.id > 0) {
|
|
|
|
|
getPostStar({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
hasStarred.value = res.status;
|
|
|
|
|
})
|
|
|
|
|
.catch((err) => {
|
|
|
|
|
console.log(err);
|
|
|
|
|
});
|
|
|
|
|
if (store.state.userInfo.id > 0) {
|
|
|
|
|
getPostStar({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
hasStarred.value = res.status;
|
|
|
|
|
})
|
|
|
|
|
.catch((err) => {
|
|
|
|
|
console.log(err);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
getPostCollection({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
hasCollected.value = res.status;
|
|
|
|
|
})
|
|
|
|
|
.catch((err) => {
|
|
|
|
|
console.log(err);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
getPostCollection({
|
|
|
|
|
id: post.value.id,
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
hasCollected.value = res.status;
|
|
|
|
|
})
|
|
|
|
|
.catch((err) => {
|
|
|
|
|
console.log(err);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|