✨ update
This commit is contained in:
5
components.d.ts
vendored
5
components.d.ts
vendored
@@ -23,6 +23,8 @@ declare module 'vue' {
|
|||||||
AImagePreviewGroup: typeof import('ant-design-vue/es')['ImagePreviewGroup']
|
AImagePreviewGroup: typeof import('ant-design-vue/es')['ImagePreviewGroup']
|
||||||
AInput: typeof import('ant-design-vue/es')['Input']
|
AInput: typeof import('ant-design-vue/es')['Input']
|
||||||
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
||||||
|
AList: typeof import('ant-design-vue/es')['List']
|
||||||
|
AListItem: typeof import('ant-design-vue/es')['ListItem']
|
||||||
AMenu: typeof import('ant-design-vue/es')['Menu']
|
AMenu: typeof import('ant-design-vue/es')['Menu']
|
||||||
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
|
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
|
||||||
AModal: typeof import('ant-design-vue/es')['Modal']
|
AModal: typeof import('ant-design-vue/es')['Modal']
|
||||||
@@ -37,6 +39,7 @@ declare module 'vue' {
|
|||||||
ATextarea: typeof import('ant-design-vue/es')['Textarea']
|
ATextarea: typeof import('ant-design-vue/es')['Textarea']
|
||||||
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
||||||
AUpload: typeof import('ant-design-vue/es')['Upload']
|
AUpload: typeof import('ant-design-vue/es')['Upload']
|
||||||
|
BellOutlined: typeof import('@ant-design/icons-vue')['BellOutlined']
|
||||||
BoxDog: typeof import('./src/components/BoxDog/BoxDog.vue')['default']
|
BoxDog: typeof import('./src/components/BoxDog/BoxDog.vue')['default']
|
||||||
Card3D: typeof import('./src/components/Card3D/Card3D.vue')['default']
|
Card3D: typeof import('./src/components/Card3D/Card3D.vue')['default']
|
||||||
CloseCircleOutlined: typeof import('@ant-design/icons-vue')['CloseCircleOutlined']
|
CloseCircleOutlined: typeof import('@ant-design/icons-vue')['CloseCircleOutlined']
|
||||||
@@ -44,8 +47,6 @@ declare module 'vue' {
|
|||||||
CommentInput: typeof import('./src/components/CommentReply/src/CommentInput/CommentInput.vue')['default']
|
CommentInput: typeof import('./src/components/CommentReply/src/CommentInput/CommentInput.vue')['default']
|
||||||
CommentList: typeof import('./src/components/CommentReply/src/CommentList/CommentList.vue')['default']
|
CommentList: typeof import('./src/components/CommentReply/src/CommentList/CommentList.vue')['default']
|
||||||
CommentReply: typeof import('./src/components/CommentReply/index.vue')['default']
|
CommentReply: typeof import('./src/components/CommentReply/index.vue')['default']
|
||||||
CopyOutlined: typeof import('@ant-design/icons-vue')['CopyOutlined']
|
|
||||||
DeleteOutlined: typeof import('@ant-design/icons-vue')['DeleteOutlined']
|
|
||||||
DynamicTitle: typeof import('./src/components/DynamicTitle/DynamicTitle.vue')['default']
|
DynamicTitle: typeof import('./src/components/DynamicTitle/DynamicTitle.vue')['default']
|
||||||
EffectsCard: typeof import('./src/components/EffectsCard/EffectsCard.vue')['default']
|
EffectsCard: typeof import('./src/components/EffectsCard/EffectsCard.vue')['default']
|
||||||
EyeOutlined: typeof import('@ant-design/icons-vue')['EyeOutlined']
|
EyeOutlined: typeof import('@ant-design/icons-vue')['EyeOutlined']
|
||||||
|
@@ -24,15 +24,30 @@
|
|||||||
</AFlex>
|
</AFlex>
|
||||||
</template>
|
</template>
|
||||||
<div style="width: 250px;height: 200px;overflow: auto;">
|
<div style="width: 250px;height: 200px;overflow: auto;">
|
||||||
<template v-for="(item) in comment.emojiList" :key="item">
|
<AList :grid="{ gutter: 0, column: 4 }" :data-source="currentEmojiList">
|
||||||
<AButton @click="insertEmoji(item.name)" type="text" shape="circle" size="large"
|
<template #loadMore>
|
||||||
class="comment-emoji-item">
|
<ADivider v-show="currentEmojiListSize<comment.emojiList.length">
|
||||||
<template #icon>
|
<AButton type="text" size="small" @click="loadMoreEmoji">{{
|
||||||
<img :width="35" :height="35" loading="lazy" :src="item.path" v-lazy-load
|
t('comment.loadingMore')
|
||||||
:alt="item.name"/>
|
}}
|
||||||
</template>
|
</AButton>
|
||||||
</AButton>
|
</ADivider>
|
||||||
</template>
|
<ADivider v-show="currentEmojiListSize>=comment.emojiList.length">
|
||||||
|
{{ t('comment.noMore') }}
|
||||||
|
</ADivider>
|
||||||
|
</template>
|
||||||
|
<template #renderItem="{ item }">
|
||||||
|
<AListItem style="display: flex;align-items: center;justify-content: center;">
|
||||||
|
<AButton @click="insertEmoji(item.name)" type="text" shape="circle" size="large"
|
||||||
|
class="comment-emoji-item">
|
||||||
|
<template #icon>
|
||||||
|
<img :width="35" :height="35" loading="lazy" :src="item.path"
|
||||||
|
:alt="item.name"/>
|
||||||
|
</template>
|
||||||
|
</AButton>
|
||||||
|
</AListItem>
|
||||||
|
</template>
|
||||||
|
</AList>
|
||||||
</div>
|
</div>
|
||||||
</ATabPane>
|
</ATabPane>
|
||||||
<ATabPane key="lottie">
|
<ATabPane key="lottie">
|
||||||
@@ -42,17 +57,30 @@
|
|||||||
</AFlex>
|
</AFlex>
|
||||||
</template>
|
</template>
|
||||||
<div style="width: 250px;height: 200px;overflow: auto;">
|
<div style="width: 250px;height: 200px;overflow: auto;">
|
||||||
<AFlex :vertical="false" align="center" justify="space-between" wrap="wrap">
|
<AList :grid="{ gutter: 0, column: 3 }" :data-source="currentLottieEmojiList">
|
||||||
<template v-for="(item) in comment.lottieEmojiList" :key="item">
|
<template #loadMore>
|
||||||
<AButton @click="insertEmoji(item.name)" type="text" shape="default" size="large"
|
<ADivider v-show="currentLottieEmojiListSize<comment.lottieEmojiList.length">
|
||||||
class="comment-emoji-item" style="width: 75px;height: 75px;">
|
<AButton type="text" size="small" @click="loadMoreLottieEmoji">{{
|
||||||
<template #icon>
|
t('comment.loadingMore')
|
||||||
<img :width="70" :height="70" loading="lazy" :src="item.path" v-lazy-load
|
}}
|
||||||
:alt="item.name"/>
|
</AButton>
|
||||||
</template>
|
</ADivider>
|
||||||
</AButton>
|
<ADivider v-show="currentLottieEmojiListSize>=comment.lottieEmojiList.length">
|
||||||
|
{{ t('comment.noMore') }}
|
||||||
|
</ADivider>
|
||||||
</template>
|
</template>
|
||||||
</AFlex>
|
<template #renderItem="{ item }">
|
||||||
|
<AListItem style="display: flex;align-items: center;justify-content: center;">
|
||||||
|
<AButton @click="insertEmoji(item.name)" type="text" shape="default" size="large"
|
||||||
|
class="comment-emoji-item" style="width: 75px;height: 75px;">
|
||||||
|
<template #icon>
|
||||||
|
<img :width="70" :height="70" loading="lazy" :src="item.path"
|
||||||
|
:alt="item.name"/>
|
||||||
|
</template>
|
||||||
|
</AButton>
|
||||||
|
</AListItem>
|
||||||
|
</template>
|
||||||
|
</AList>
|
||||||
</div>
|
</div>
|
||||||
</ATabPane>
|
</ATabPane>
|
||||||
</ATabs>
|
</ATabs>
|
||||||
@@ -153,6 +181,30 @@ const commentSlideCaptchaEvent = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
const emojiType = ref<string>("qq");
|
const emojiType = ref<string>("qq");
|
||||||
|
const currentEmojiList = ref<any[]>(comment.emojiList.slice(0, 20));
|
||||||
|
const currentEmojiListSize = ref<number>(20);
|
||||||
|
const currentLottieEmojiList = ref<any[]>(comment.lottieEmojiList.slice(0, 15));
|
||||||
|
const currentLottieEmojiListSize = ref<number>(15);
|
||||||
|
/**
|
||||||
|
* 加载更多表情
|
||||||
|
*/
|
||||||
|
const loadMoreEmoji = async () => {
|
||||||
|
if (currentEmojiListSize.value >= comment.emojiList.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
currentEmojiListSize.value += 20;
|
||||||
|
currentEmojiList.value = comment.emojiList.slice(0, currentEmojiListSize.value);
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 加载更多Lottie表情
|
||||||
|
*/
|
||||||
|
const loadMoreLottieEmoji = async () => {
|
||||||
|
if (currentLottieEmojiListSize.value >= comment.lottieEmojiList.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
currentLottieEmojiListSize.value += 15;
|
||||||
|
currentLottieEmojiList.value = comment.lottieEmojiList.slice(0, currentLottieEmojiListSize.value);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 聚焦事件
|
* 聚焦事件
|
||||||
@@ -196,11 +248,11 @@ async function commentSubmit(point: any) {
|
|||||||
const content = commentContent.value.replace(/\r\n/g, '<br/>').replace(/\n/g, '<br/>').replace(/\s/g, ' ');
|
const content = commentContent.value.replace(/\r\n/g, '<br/>').replace(/\n/g, '<br/>').replace(/\s/g, ' ');
|
||||||
const regex = /\[((1[0-6][0-6]|[1-9]?[0-9])\.gif)]/g; // 匹配 [1.gif] 的字符串
|
const regex = /\[((1[0-6][0-6]|[1-9]?[0-9])\.gif)]/g; // 匹配 [1.gif] 的字符串
|
||||||
const contentWithEmoji = content.replace(regex, (_match, p1) => {
|
const contentWithEmoji = content.replace(regex, (_match, p1) => {
|
||||||
return `<img style="width: 30px; height: 30px;" loading="lazy" src="/emoji/qq/gif/${p1}" alt="emoji ${p1}" />`;
|
return `<img width="30px" height="30px" loading="lazy" src="/emoji/qq/gif/${p1}" alt="emoji ${p1}" />`;
|
||||||
});
|
});
|
||||||
const regexWithLottieEmoji = /\:((1[0-0-8]|[1-9]?[0-9])\.gif)\:/g; // 匹配 :1.gif: 的字符串
|
const regexWithLottieEmoji = /\:((1[0-0-8]|[1-9]?[0-9])\.gif)\:/g; // 匹配 :1.gif: 的字符串
|
||||||
const contentWithLottieEmoji = contentWithEmoji.replace(regexWithLottieEmoji, (_match, p1) => {
|
const contentWithLottieEmoji = contentWithEmoji.replace(regexWithLottieEmoji, (_match, p1) => {
|
||||||
return `<img style="width: 80px; height: 80px;" loading="lazy" src="/emoji/qq/lottie/${p1}" alt="emoji ${p1}" />`;
|
return `<img width="80px" height="80px" loading="lazy" src="/emoji/qq/lottie/${p1}" alt="emoji ${p1}" />`;
|
||||||
});
|
});
|
||||||
const commentParams: object = {
|
const commentParams: object = {
|
||||||
user_id: user.user.uid,
|
user_id: user.user.uid,
|
||||||
@@ -219,6 +271,7 @@ async function commentSubmit(point: any) {
|
|||||||
showSubmitCaptcha.value = false;
|
showSubmitCaptcha.value = false;
|
||||||
await getCommentList();
|
await getCommentList();
|
||||||
} else {
|
} else {
|
||||||
|
showSubmitCaptcha.value = false;
|
||||||
message.error(result.message || t('comment.commentError'));
|
message.error(result.message || t('comment.commentError'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -245,6 +298,14 @@ const getSlideCaptchaDataThrottled = useThrottleFn(comment.getSlideCaptchaData,
|
|||||||
* 显示滑动验证码
|
* 显示滑动验证码
|
||||||
*/
|
*/
|
||||||
async function showSlideCaptcha() {
|
async function showSlideCaptcha() {
|
||||||
|
if (commentContent.value.trim() === "") {
|
||||||
|
message.error(t('comment.commentContentNotEmpty'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (comment.imageList.length > 3) {
|
||||||
|
message.error(t('comment.maxImageCount'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
const res = await comment.getSlideCaptchaData();
|
const res = await comment.getSlideCaptchaData();
|
||||||
if (res) {
|
if (res) {
|
||||||
showSubmitCaptcha.value = true;
|
showSubmitCaptcha.value = true;
|
||||||
|
@@ -104,14 +104,6 @@
|
|||||||
<WarningOutlined/>
|
<WarningOutlined/>
|
||||||
{{ t('comment.report') }}
|
{{ t('comment.report') }}
|
||||||
</AMenuItem>
|
</AMenuItem>
|
||||||
<AMenuItem key="copy">
|
|
||||||
<CopyOutlined/>
|
|
||||||
{{ t('comment.copy') }}
|
|
||||||
</AMenuItem>
|
|
||||||
<AMenuItem key="delete">
|
|
||||||
<DeleteOutlined/>
|
|
||||||
{{ t('comment.delete') }}
|
|
||||||
</AMenuItem>
|
|
||||||
</AMenu>
|
</AMenu>
|
||||||
</template>
|
</template>
|
||||||
</ADropdown>
|
</ADropdown>
|
||||||
|
@@ -8,11 +8,8 @@
|
|||||||
{{ t('comment.cancelReply') }}
|
{{ t('comment.cancelReply') }}
|
||||||
</AButton>
|
</AButton>
|
||||||
</AFlex>
|
</AFlex>
|
||||||
<!-- 回复头像-->
|
|
||||||
<AFlex :vertical="false" class="reply-input-content">
|
<AFlex :vertical="false" class="reply-input-content">
|
||||||
<AFlex :vertical="true" class="reply-input-avatar">
|
|
||||||
<AAvatar :size="40" shape="circle" :src="user.user.userInfo.avatar"/>
|
|
||||||
</AFlex>
|
|
||||||
<!-- 评论输入框 -->
|
<!-- 评论输入框 -->
|
||||||
<AFlex :vertical="true" class="reply-input-content-text">
|
<AFlex :vertical="true" class="reply-input-content-text">
|
||||||
<ATextarea :rows="3" class="comment-text-reply"
|
<ATextarea :rows="3" class="comment-text-reply"
|
||||||
@@ -33,15 +30,31 @@
|
|||||||
</AFlex>
|
</AFlex>
|
||||||
</template>
|
</template>
|
||||||
<div style="width: 250px;height: 200px;overflow: auto;">
|
<div style="width: 250px;height: 200px;overflow: auto;">
|
||||||
<template v-for="(item) in comment.emojiList" :key="item">
|
<AList :grid="{ gutter: 0, column: 4 }" :data-source="currentEmojiList">
|
||||||
<AButton @click="insertEmojiToReplyContent(item.name)" type="text" shape="circle" size="large"
|
<template #loadMore>
|
||||||
class="comment-emoji-item">
|
<ADivider v-show="currentEmojiListSize<comment.emojiList.length">
|
||||||
<template #icon>
|
<AButton type="text" size="small" @click="loadMoreEmoji">{{
|
||||||
<img :width="35" :height="35" loading="lazy" :src="item.path" v-lazy-load
|
t('comment.loadingMore')
|
||||||
:alt="item.name"/>
|
}}
|
||||||
</template>
|
</AButton>
|
||||||
</AButton>
|
</ADivider>
|
||||||
</template>
|
<ADivider v-show="currentEmojiListSize>=comment.emojiList.length">
|
||||||
|
{{ t('comment.noMore') }}
|
||||||
|
</ADivider>
|
||||||
|
</template>
|
||||||
|
<template #renderItem="{ item }">
|
||||||
|
<AListItem style="display: flex;align-items: center;justify-content: center;">
|
||||||
|
<AButton @click="insertEmojiToReplyContent(item.name)" type="text" shape="circle"
|
||||||
|
size="large"
|
||||||
|
class="comment-emoji-item">
|
||||||
|
<template #icon>
|
||||||
|
<img :width="35" :height="35" loading="lazy" :src="item.path"
|
||||||
|
:alt="item.name"/>
|
||||||
|
</template>
|
||||||
|
</AButton>
|
||||||
|
</AListItem>
|
||||||
|
</template>
|
||||||
|
</AList>
|
||||||
</div>
|
</div>
|
||||||
</ATabPane>
|
</ATabPane>
|
||||||
<ATabPane key="lottie">
|
<ATabPane key="lottie">
|
||||||
@@ -51,18 +64,31 @@
|
|||||||
</AFlex>
|
</AFlex>
|
||||||
</template>
|
</template>
|
||||||
<div style="width: 250px;height: 200px;overflow: auto;">
|
<div style="width: 250px;height: 200px;overflow: auto;">
|
||||||
<AFlex :vertical="false" align="center" justify="space-between" wrap="wrap">
|
<AList :grid="{ gutter: 0, column: 3 }" :data-source="currentLottieEmojiList">
|
||||||
<template v-for="(item) in comment.lottieEmojiList" :key="item">
|
<template #loadMore>
|
||||||
<AButton @click="insertEmojiToReplyContent(item.name)" type="text" shape="default"
|
<ADivider v-show="currentLottieEmojiListSize<comment.lottieEmojiList.length">
|
||||||
size="large"
|
<AButton type="text" size="small" @click="loadMoreLottieEmoji">{{
|
||||||
class="comment-emoji-item" style="width: 75px;height: 75px;">
|
t('comment.loadingMore')
|
||||||
<template #icon>
|
}}
|
||||||
<img :width="70" :height="70" loading="lazy" :src="item.path" v-lazy-load
|
</AButton>
|
||||||
:alt="item.name"/>
|
</ADivider>
|
||||||
</template>
|
<ADivider v-show="currentLottieEmojiListSize>=comment.lottieEmojiList.length">
|
||||||
</AButton>
|
{{ t('comment.noMore') }}
|
||||||
|
</ADivider>
|
||||||
</template>
|
</template>
|
||||||
</AFlex>
|
<template #renderItem="{ item }">
|
||||||
|
<AListItem style="display: flex;align-items: center;justify-content: center;">
|
||||||
|
<AButton @click="insertEmojiToReplyContent(item.name)" type="text" shape="default"
|
||||||
|
size="large"
|
||||||
|
class="comment-emoji-item" style="width: 75px;height: 75px;">
|
||||||
|
<template #icon>
|
||||||
|
<img :width="70" :height="70" loading="lazy" :src="item.path"
|
||||||
|
:alt="item.name"/>
|
||||||
|
</template>
|
||||||
|
</AButton>
|
||||||
|
</AListItem>
|
||||||
|
</template>
|
||||||
|
</AList>
|
||||||
</div>
|
</div>
|
||||||
</ATabPane>
|
</ATabPane>
|
||||||
</ATabs>
|
</ATabs>
|
||||||
@@ -166,6 +192,31 @@ const commentSlideCaptchaEvent = {
|
|||||||
};
|
};
|
||||||
const emojiType = ref<string>("qq");
|
const emojiType = ref<string>("qq");
|
||||||
|
|
||||||
|
const currentEmojiList = ref<any[]>(comment.emojiList.slice(0, 20));
|
||||||
|
const currentEmojiListSize = ref<number>(20);
|
||||||
|
const currentLottieEmojiList = ref<any[]>(comment.lottieEmojiList.slice(0, 15));
|
||||||
|
const currentLottieEmojiListSize = ref<number>(15);
|
||||||
|
/**
|
||||||
|
* 加载更多表情
|
||||||
|
*/
|
||||||
|
const loadMoreEmoji = async () => {
|
||||||
|
if (currentEmojiListSize.value >= comment.emojiList.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
currentEmojiListSize.value += 20;
|
||||||
|
currentEmojiList.value = comment.emojiList.slice(0, currentEmojiListSize.value);
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 加载更多Lottie表情
|
||||||
|
*/
|
||||||
|
const loadMoreLottieEmoji = async () => {
|
||||||
|
if (currentLottieEmojiListSize.value >= comment.lottieEmojiList.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
currentLottieEmojiListSize.value += 15;
|
||||||
|
currentLottieEmojiList.value = comment.lottieEmojiList.slice(0, currentLottieEmojiListSize.value);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 切换表情类型
|
* 切换表情类型
|
||||||
* @param type
|
* @param type
|
||||||
@@ -210,11 +261,11 @@ async function replySubmit(point: any) {
|
|||||||
const content = replyContent.value.replace(/\r\n/g, '<br/>').replace(/\n/g, '<br/>').replace(/\s/g, ' ');
|
const content = replyContent.value.replace(/\r\n/g, '<br/>').replace(/\n/g, '<br/>').replace(/\s/g, ' ');
|
||||||
const regex = /\[((1[0-6][0-6]|[1-9]?[0-9])\.gif)\]/g; // 匹配 [1.gif] 的字符串
|
const regex = /\[((1[0-6][0-6]|[1-9]?[0-9])\.gif)\]/g; // 匹配 [1.gif] 的字符串
|
||||||
const contentWithEmoji = content.replace(regex, (_match, p1) => {
|
const contentWithEmoji = content.replace(regex, (_match, p1) => {
|
||||||
return `<img style="width: 30px; height: 30px;" loading="lazy" src="/emoji/qq/gif/${p1}" alt="emoji ${p1}" />`;
|
return `<img width="30px" height="30px" loading="lazy" src="/emoji/qq/gif/${p1}" alt="emoji ${p1}" />`;
|
||||||
});
|
});
|
||||||
const regexWithLottieEmoji = /\:((1[0-0-8]|[1-9]?[0-9])\.gif)\:/g; // 匹配 :1.gif: 的字符串
|
const regexWithLottieEmoji = /\:((1[0-0-8]|[1-9]?[0-9])\.gif)\:/g; // 匹配 :1.gif: 的字符串
|
||||||
const contentWithLottieEmoji = contentWithEmoji.replace(regexWithLottieEmoji, (_match, p1) => {
|
const contentWithLottieEmoji = contentWithEmoji.replace(regexWithLottieEmoji, (_match, p1) => {
|
||||||
return `<img style="width: 80px; height: 80px;" loading="lazy" src="/emoji/qq/lottie/${p1}" alt="emoji ${p1}" />`;
|
return `<img width="80px" height="80px" loading="lazy" src="/emoji/qq/lottie/${p1}" alt="emoji ${p1}" />`;
|
||||||
});
|
});
|
||||||
const replyParams: {
|
const replyParams: {
|
||||||
images: any;
|
images: any;
|
||||||
@@ -247,6 +298,7 @@ async function replySubmit(point: any) {
|
|||||||
comment.commentMap[props.item.id].reply_count++;
|
comment.commentMap[props.item.id].reply_count++;
|
||||||
message.success(t('comment.replySuccess'));
|
message.success(t('comment.replySuccess'));
|
||||||
} else {
|
} else {
|
||||||
|
showSubmitCaptcha.value = false;
|
||||||
message.error(t('comment.replyError'));
|
message.error(t('comment.replyError'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,6 +323,14 @@ const getSlideCaptchaDataThrottled = useThrottleFn(comment.getSlideCaptchaData,
|
|||||||
* 显示滑动验证码
|
* 显示滑动验证码
|
||||||
*/
|
*/
|
||||||
async function showSlideCaptcha() {
|
async function showSlideCaptcha() {
|
||||||
|
if (replyContent.value.trim() === "") {
|
||||||
|
message.error(t('comment.commentContentNotEmpty'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (comment.imageList.length > 3) {
|
||||||
|
message.error(t('comment.maxImageCount'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
const res = await comment.getSlideCaptchaData();
|
const res = await comment.getSlideCaptchaData();
|
||||||
if (res) {
|
if (res) {
|
||||||
showSubmitCaptcha.value = true;
|
showSubmitCaptcha.value = true;
|
||||||
|
@@ -22,10 +22,10 @@
|
|||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|
||||||
.reply-input-content-text {
|
.reply-input-content-text {
|
||||||
margin-left: 10px;
|
//margin-left: 10px;
|
||||||
|
|
||||||
.comment-text-reply {
|
.comment-text-reply {
|
||||||
width: 550px;
|
width: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment-actions-reply {
|
.comment-actions-reply {
|
||||||
|
@@ -80,14 +80,9 @@
|
|||||||
<template #overlay>
|
<template #overlay>
|
||||||
<AMenu>
|
<AMenu>
|
||||||
<AMenuItem key="report">
|
<AMenuItem key="report">
|
||||||
|
<WarningOutlined/>
|
||||||
{{ t('comment.report') }}
|
{{ t('comment.report') }}
|
||||||
</AMenuItem>
|
</AMenuItem>
|
||||||
<AMenuItem key="copy">
|
|
||||||
{{ t('comment.copy') }}
|
|
||||||
</AMenuItem>
|
|
||||||
<AMenuItem key="delete">
|
|
||||||
{{ t('comment.delete') }}
|
|
||||||
</AMenuItem>
|
|
||||||
</AMenu>
|
</AMenu>
|
||||||
</template>
|
</template>
|
||||||
</ADropdown>
|
</ADropdown>
|
||||||
|
@@ -10,11 +10,8 @@
|
|||||||
{{ t('comment.cancelReply') }}
|
{{ t('comment.cancelReply') }}
|
||||||
</AButton>
|
</AButton>
|
||||||
</AFlex>
|
</AFlex>
|
||||||
<!-- 回复头像-->
|
|
||||||
<AFlex :vertical="false" class="reply-input-content-child">
|
<AFlex :vertical="false" class="reply-input-content-child">
|
||||||
<AFlex :vertical="true" class="reply-input-avatar-child">
|
|
||||||
<AAvatar :size="40" shape="circle" :src="user.user.userInfo.avatar"/>
|
|
||||||
</AFlex>
|
|
||||||
<!-- 评论输入框 -->
|
<!-- 评论输入框 -->
|
||||||
<AFlex :vertical="true" class="reply-input-content-text-child">
|
<AFlex :vertical="true" class="reply-input-content-text-child">
|
||||||
<ATextarea :rows="3" class="comment-text-reply-child"
|
<ATextarea :rows="3" class="comment-text-reply-child"
|
||||||
@@ -36,16 +33,31 @@
|
|||||||
</AFlex>
|
</AFlex>
|
||||||
</template>
|
</template>
|
||||||
<div style="width: 250px;height: 200px;overflow: auto;">
|
<div style="width: 250px;height: 200px;overflow: auto;">
|
||||||
<template v-for="(item) in comment.emojiList" :key="item">
|
<AList :grid="{ gutter: 0, column: 4 }" :data-source="currentEmojiList">
|
||||||
<AButton @click="insertEmojiToReplyReplyContent(item.name)" type="text" shape="circle"
|
<template #loadMore>
|
||||||
size="large"
|
<ADivider v-show="currentEmojiListSize<comment.emojiList.length">
|
||||||
class="comment-emoji-item">
|
<AButton type="text" size="small" @click="loadMoreEmoji">{{
|
||||||
<template #icon>
|
t('comment.loadingMore')
|
||||||
<img :width="35" :height="35" loading="lazy" :src="item.path" v-lazy-load
|
}}
|
||||||
:alt="item.name"/>
|
</AButton>
|
||||||
</template>
|
</ADivider>
|
||||||
</AButton>
|
<ADivider v-show="currentEmojiListSize>=comment.emojiList.length">
|
||||||
</template>
|
{{ t('comment.noMore') }}
|
||||||
|
</ADivider>
|
||||||
|
</template>
|
||||||
|
<template #renderItem="{ item }">
|
||||||
|
<AListItem style="display: flex;align-items: center;justify-content: center;">
|
||||||
|
<AButton @click="insertEmojiToReplyReplyContent(item.name)" type="text" shape="circle"
|
||||||
|
size="large"
|
||||||
|
class="comment-emoji-item">
|
||||||
|
<template #icon>
|
||||||
|
<img :width="35" :height="35" loading="lazy" :src="item.path"
|
||||||
|
:alt="item.name"/>
|
||||||
|
</template>
|
||||||
|
</AButton>
|
||||||
|
</AListItem>
|
||||||
|
</template>
|
||||||
|
</AList>
|
||||||
</div>
|
</div>
|
||||||
</ATabPane>
|
</ATabPane>
|
||||||
<ATabPane key="lottie">
|
<ATabPane key="lottie">
|
||||||
@@ -55,18 +67,31 @@
|
|||||||
</AFlex>
|
</AFlex>
|
||||||
</template>
|
</template>
|
||||||
<div style="width: 250px;height: 200px;overflow: auto;">
|
<div style="width: 250px;height: 200px;overflow: auto;">
|
||||||
<AFlex :vertical="false" align="center" justify="space-between" wrap="wrap">
|
<AList :grid="{ gutter: 0, column: 3 }" :data-source="currentLottieEmojiList">
|
||||||
<template v-for="(item) in comment.lottieEmojiList" :key="item">
|
<template #loadMore>
|
||||||
<AButton @click="insertEmojiToReplyReplyContent(item.name)" type="text" shape="default"
|
<ADivider v-show="currentLottieEmojiListSize<comment.lottieEmojiList.length">
|
||||||
size="large"
|
<AButton type="text" size="small" @click="loadMoreLottieEmoji">{{
|
||||||
class="comment-emoji-item" style="width: 75px;height: 75px;">
|
t('comment.loadingMore')
|
||||||
<template #icon>
|
}}
|
||||||
<img :width="70" :height="70" loading="lazy" :src="item.path" v-lazy-load
|
</AButton>
|
||||||
:alt="item.name"/>
|
</ADivider>
|
||||||
</template>
|
<ADivider v-show="currentLottieEmojiListSize>=comment.lottieEmojiList.length">
|
||||||
</AButton>
|
{{ t('comment.noMore') }}
|
||||||
|
</ADivider>
|
||||||
</template>
|
</template>
|
||||||
</AFlex>
|
<template #renderItem="{ item }">
|
||||||
|
<AListItem style="display: flex;align-items: center;justify-content: center;">
|
||||||
|
<AButton @click="insertEmojiToReplyReplyContent(item.name)" type="text" shape="default"
|
||||||
|
size="large"
|
||||||
|
class="comment-emoji-item" style="width: 75px;height: 75px;">
|
||||||
|
<template #icon>
|
||||||
|
<img :width="70" :height="70" loading="lazy" :src="item.path"
|
||||||
|
:alt="item.name"/>
|
||||||
|
</template>
|
||||||
|
</AButton>
|
||||||
|
</AListItem>
|
||||||
|
</template>
|
||||||
|
</AList>
|
||||||
</div>
|
</div>
|
||||||
</ATabPane>
|
</ATabPane>
|
||||||
</ATabs>
|
</ATabs>
|
||||||
@@ -179,6 +204,31 @@ const commentSlideCaptchaEvent = {
|
|||||||
};
|
};
|
||||||
const emojiType = ref<string>("qq");
|
const emojiType = ref<string>("qq");
|
||||||
|
|
||||||
|
const currentEmojiList = ref<any[]>(comment.emojiList.slice(0, 20));
|
||||||
|
const currentEmojiListSize = ref<number>(20);
|
||||||
|
const currentLottieEmojiList = ref<any[]>(comment.lottieEmojiList.slice(0, 15));
|
||||||
|
const currentLottieEmojiListSize = ref<number>(15);
|
||||||
|
/**
|
||||||
|
* 加载更多表情
|
||||||
|
*/
|
||||||
|
const loadMoreEmoji = async () => {
|
||||||
|
if (currentEmojiListSize.value >= comment.emojiList.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
currentEmojiListSize.value += 20;
|
||||||
|
currentEmojiList.value = comment.emojiList.slice(0, currentEmojiListSize.value);
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 加载更多Lottie表情
|
||||||
|
*/
|
||||||
|
const loadMoreLottieEmoji = async () => {
|
||||||
|
if (currentLottieEmojiListSize.value >= comment.lottieEmojiList.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
currentLottieEmojiListSize.value += 15;
|
||||||
|
currentLottieEmojiList.value = comment.lottieEmojiList.slice(0, currentLottieEmojiListSize.value);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 切换表情类型
|
* 切换表情类型
|
||||||
* @param type
|
* @param type
|
||||||
@@ -223,11 +273,11 @@ async function replyReplySubmit(point: any) {
|
|||||||
const content = replyReplyContent.value.replace(/\r\n/g, '<br/>').replace(/\n/g, '<br/>').replace(/\s/g, ' ');
|
const content = replyReplyContent.value.replace(/\r\n/g, '<br/>').replace(/\n/g, '<br/>').replace(/\s/g, ' ');
|
||||||
const regex = /\[((1[0-6][0-6]|[1-9]?[0-9])\.gif)]/g; // 匹配 [1.gif] 的字符串
|
const regex = /\[((1[0-6][0-6]|[1-9]?[0-9])\.gif)]/g; // 匹配 [1.gif] 的字符串
|
||||||
const contentWithEmoji = content.replace(regex, (_match, p1) => {
|
const contentWithEmoji = content.replace(regex, (_match, p1) => {
|
||||||
return `<img style="width: 30px; height: 30px;" loading="lazy" src="/emoji/qq/gif/${p1}" alt="emoji ${p1}" />`;
|
return `<img width="30px" height="30px" loading="lazy" src="/emoji/qq/gif/${p1}" alt="emoji ${p1}" />`;
|
||||||
});
|
});
|
||||||
const regexWithLottieEmoji = /:((1[0-0-8]|[1-9]?[0-9])\.gif):/g; // 匹配 :1.gif: 的字符串
|
const regexWithLottieEmoji = /:((1[0-0-8]|[1-9]?[0-9])\.gif):/g; // 匹配 :1.gif: 的字符串
|
||||||
const contentWithLottieEmoji = contentWithEmoji.replace(regexWithLottieEmoji, (_match, p1) => {
|
const contentWithLottieEmoji = contentWithEmoji.replace(regexWithLottieEmoji, (_match, p1) => {
|
||||||
return `<img style="width: 80px; height: 80px;" loading="lazy" src="/emoji/qq/lottie/${p1}" alt="emoji ${p1}" />`;
|
return `<img width="80px" height="80px" loading="lazy" src="/emoji/qq/lottie/${p1}" alt="emoji ${p1}" />`;
|
||||||
});
|
});
|
||||||
const replyParams: ReplyCommentParams = {
|
const replyParams: ReplyCommentParams = {
|
||||||
user_id: user.user.uid,
|
user_id: user.user.uid,
|
||||||
@@ -252,6 +302,7 @@ async function replyReplySubmit(point: any) {
|
|||||||
comment.commentMap[props.item.id].reply_count++;
|
comment.commentMap[props.item.id].reply_count++;
|
||||||
message.success(t('comment.replySuccess'));
|
message.success(t('comment.replySuccess'));
|
||||||
} else {
|
} else {
|
||||||
|
showSubmitCaptcha.value = false;
|
||||||
message.error(t('comment.replyError'));
|
message.error(t('comment.replyError'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -262,6 +313,14 @@ const getSlideCaptchaDataThrottled = useThrottleFn(comment.getSlideCaptchaData,
|
|||||||
* 显示滑动验证码
|
* 显示滑动验证码
|
||||||
*/
|
*/
|
||||||
async function showSlideCaptcha() {
|
async function showSlideCaptcha() {
|
||||||
|
if (replyReplyContent.value.trim() === "") {
|
||||||
|
message.error(t('comment.commentContentNotEmpty'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (comment.imageList.length > 3) {
|
||||||
|
message.error(t('comment.maxImageCount'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
const res = await comment.getSlideCaptchaData();
|
const res = await comment.getSlideCaptchaData();
|
||||||
if (res) {
|
if (res) {
|
||||||
showSubmitCaptcha.value = true;
|
showSubmitCaptcha.value = true;
|
||||||
|
@@ -22,10 +22,10 @@
|
|||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|
||||||
.reply-input-content-text-child {
|
.reply-input-content-text-child {
|
||||||
margin-left: 10px;
|
//margin-left: 10px;
|
||||||
|
|
||||||
.comment-text-reply-child {
|
.comment-text-reply-child {
|
||||||
width: 480px;
|
width: 530px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment-actions-reply-child {
|
.comment-actions-reply-child {
|
||||||
|
@@ -16,27 +16,6 @@
|
|||||||
<label for="toggle-box-checkbox" class="toggle-box-label-left"></label>
|
<label for="toggle-box-checkbox" class="toggle-box-label-left"></label>
|
||||||
<label for="toggle-box-checkbox" class="toggle-box-label"></label>
|
<label for="toggle-box-checkbox" class="toggle-box-label"></label>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-right: 20px;">
|
|
||||||
<ADropdown>
|
|
||||||
<template #overlay>
|
|
||||||
<AMenu @click="(e: any)=>{
|
|
||||||
changeTheme(e.key)
|
|
||||||
}">
|
|
||||||
<AMenuItem v-for="(color, name) in variables" :key="name" :value="color">
|
|
||||||
<div
|
|
||||||
v-bind:style="{ backgroundColor: name as string, width: '20px', height: '20px', borderRadius: '20%' }">
|
|
||||||
</div>
|
|
||||||
</AMenuItem>
|
|
||||||
</AMenu>
|
|
||||||
</template>
|
|
||||||
<AButton type="text" size="large">
|
|
||||||
<div
|
|
||||||
v-bind:style="{ backgroundColor: app.themeName, width: '20px', height: '20px', borderRadius: '20%' }">
|
|
||||||
</div>
|
|
||||||
</AButton>
|
|
||||||
</ADropdown>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div style="margin-right: 20px;">
|
<div style="margin-right: 20px;">
|
||||||
<ADropdown>
|
<ADropdown>
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
@@ -47,9 +26,7 @@
|
|||||||
<AMenuItem key="en">{{ t("landing.english") }}</AMenuItem>
|
<AMenuItem key="en">{{ t("landing.english") }}</AMenuItem>
|
||||||
</AMenu>
|
</AMenu>
|
||||||
</template>
|
</template>
|
||||||
<AButton type="text" size="large">
|
<AButton type="text" size="large" :icon="h(TranslationOutlined)">
|
||||||
{{ lang.lang === 'zh' ? '中文' : 'English' }}
|
|
||||||
<DownOutlined/>
|
|
||||||
</AButton>
|
</AButton>
|
||||||
</ADropdown>
|
</ADropdown>
|
||||||
|
|
||||||
@@ -67,24 +44,20 @@
|
|||||||
|
|
||||||
|
|
||||||
import useStore from "@/store/index.ts";
|
import useStore from "@/store/index.ts";
|
||||||
import {ref} from "vue";
|
import {h, ref} from "vue";
|
||||||
import {DownOutlined} from '@ant-design/icons-vue';
|
import {TranslationOutlined} from '@ant-design/icons-vue';
|
||||||
import {useI18n} from "vue-i18n";
|
import {useI18n} from "vue-i18n";
|
||||||
import variables from "@/assets/styles/colors.module.scss";
|
|
||||||
import {useRouter} from "vue-router";
|
import {useRouter} from "vue-router";
|
||||||
|
|
||||||
|
|
||||||
const {t, locale} = useI18n();
|
const {t, locale} = useI18n();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const lang = useStore().lang;
|
const lang = useStore().lang;
|
||||||
|
|
||||||
async function changeLang(language: any) {
|
async function changeLang(language: any) {
|
||||||
lang.lang = language;
|
lang.lang = language;
|
||||||
locale.value = language;
|
locale.value = language;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function changeTheme(theme: any) {
|
|
||||||
app.setThemeName(theme);
|
|
||||||
}
|
|
||||||
|
|
||||||
const app = useStore().theme;
|
const app = useStore().theme;
|
||||||
const isDarkMode = ref<boolean>(app.darkMode === "dark");
|
const isDarkMode = ref<boolean>(app.darkMode === "dark");
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
transition: background-color 0.3s;
|
transition: background-color 0.3s;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
||||||
|
|
||||||
.landing-header-logo {
|
.landing-header-logo {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
33
src/layout/default/Header/Header.vue
Normal file
33
src/layout/default/Header/Header.vue
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<template>
|
||||||
|
<header class="header-main">
|
||||||
|
<AFlex :vertical="false" align="center" justify="flex-end" class="header-logo-container">
|
||||||
|
<AAvatar :size="50" :src="logo"/>
|
||||||
|
<img style="width: 200px;" src="@/assets/images/logo.png" alt="logo">
|
||||||
|
</AFlex>
|
||||||
|
<AFlex :vertical="false" align="center" justify="flex-end" class="header-menu-container">
|
||||||
|
<AFlex :vertical="false" align="center" justify="flex-start" class="header-menu-item">
|
||||||
|
<ABadge count="0" :numberStyle="{
|
||||||
|
marginTop: '5px',
|
||||||
|
}">
|
||||||
|
<AButton type="text" shape="circle" size="middle" class="header-menu-item-btn"
|
||||||
|
:icon="h(BellOutlined)"/>
|
||||||
|
</ABadge>
|
||||||
|
</AFlex>
|
||||||
|
<AFlex :vertical="false" align="center" justify="flex-start" class="header-user-container">
|
||||||
|
<AAvatar :size="35" class="header-user-avatar" :src="user.user.userInfo.avatar"/>
|
||||||
|
<AButton type="text" size="small" class="header-user-btn">landaiqing</AButton>
|
||||||
|
</AFlex>
|
||||||
|
</AFlex>
|
||||||
|
</header>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import logo from "@/assets/svgs/logo-schisandra.svg";
|
||||||
|
import useStore from "@/store";
|
||||||
|
import {BellOutlined} from "@ant-design/icons-vue";
|
||||||
|
import {h} from "vue";
|
||||||
|
|
||||||
|
const user = useStore().user;
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss" src="./index.scss">
|
||||||
|
|
||||||
|
</style>
|
40
src/layout/default/Header/index.scss
Normal file
40
src/layout/default/Header/index.scss
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
.header-main {
|
||||||
|
height: 60px;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 1200px;
|
||||||
|
min-height: 60px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: rgba(255, 255, 255, 0.38);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
z-index: 3;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
||||||
|
|
||||||
|
.header-logo-container {
|
||||||
|
min-width: 280px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-menu-container {
|
||||||
|
width: 30%;
|
||||||
|
|
||||||
|
.header-menu-item {
|
||||||
|
min-width: 60px;
|
||||||
|
|
||||||
|
.header-menu-item-btn {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-user-container {
|
||||||
|
min-width: 130px;
|
||||||
|
|
||||||
|
.header-user-avatar {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -101,5 +101,7 @@ export default {
|
|||||||
replySuccess: 'reply success!',
|
replySuccess: 'reply success!',
|
||||||
replyError: 'reply failed!',
|
replyError: 'reply failed!',
|
||||||
illegalImage: 'illegal image!',
|
illegalImage: 'illegal image!',
|
||||||
|
loadingMore: 'loading more',
|
||||||
|
noMore: 'no more',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -100,6 +100,8 @@ export default {
|
|||||||
replySuccess: '回复成功!',
|
replySuccess: '回复成功!',
|
||||||
replyError: '回复失败!',
|
replyError: '回复失败!',
|
||||||
illegalImage: ' 非法图片!',
|
illegalImage: ' 非法图片!',
|
||||||
|
loadingMore: '加载更多',
|
||||||
|
noMore: '没有更多了',
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -3,7 +3,6 @@ import login from './modules/login';
|
|||||||
|
|
||||||
import useStore from "@/store";
|
import useStore from "@/store";
|
||||||
import {message} from "ant-design-vue";
|
import {message} from "ant-design-vue";
|
||||||
import {close, start} from '@/components/Nprogress/nprogress.ts';
|
|
||||||
import notFound from "./modules/notFound.ts";
|
import notFound from "./modules/notFound.ts";
|
||||||
import landing from "./modules/landing.ts";
|
import landing from "./modules/landing.ts";
|
||||||
import mainRouter from "./modules/main_router.ts";
|
import mainRouter from "./modules/main_router.ts";
|
||||||
@@ -26,7 +25,7 @@ const router: Router = createRouter({
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.beforeEach((to, _from, next) => {
|
router.beforeEach((to, _from, next) => {
|
||||||
start();
|
// start();
|
||||||
const user = useStore().user;
|
const user = useStore().user;
|
||||||
const token: string | undefined = user.user.refreshToken;
|
const token: string | undefined = user.user.refreshToken;
|
||||||
const userId: string | undefined = user.user.uid;
|
const userId: string | undefined = user.user.uid;
|
||||||
@@ -59,6 +58,6 @@ router.beforeEach((to, _from, next) => {
|
|||||||
|
|
||||||
router.afterEach(() => {
|
router.afterEach(() => {
|
||||||
// 关闭进度条
|
// 关闭进度条
|
||||||
close();
|
// close();
|
||||||
});
|
});
|
||||||
export default router;
|
export default router;
|
||||||
|
@@ -32,10 +32,6 @@ const {onAuthRequired, onResponseRefreshToken} = createServerTokenAuthentication
|
|||||||
user.user.accessToken = access_token;
|
user.user.accessToken = access_token;
|
||||||
user.user.refreshToken = refresh_token;
|
user.user.refreshToken = refresh_token;
|
||||||
user.user.uid = uid;
|
user.user.uid = uid;
|
||||||
} else {
|
|
||||||
message.error(i18n.global.t('error.loginExpired'));
|
|
||||||
localStorage.removeItem('user');
|
|
||||||
window.location.href = '/login';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,28 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center;">
|
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center;">
|
||||||
<AButton @click="handleClick">获取登录用户角色</AButton>
|
<Header/>
|
||||||
{{ data }}
|
|
||||||
|
|
||||||
<CommentReply/>
|
<CommentReply/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {useRequest} from "alova/client";
|
|
||||||
import {getUserPermissions} from "@/api/user";
|
|
||||||
import useStore from "@/store";
|
import useStore from "@/store";
|
||||||
import CommentReply from "@/components/CommentReply/index.vue";
|
import CommentReply from "@/components/CommentReply/index.vue";
|
||||||
import {onMounted} from "vue";
|
import {onMounted} from "vue";
|
||||||
|
import Header from "@/layout/default/Header/Header.vue";
|
||||||
|
|
||||||
const websocket = useStore().websocket;
|
const websocket = useStore().websocket;
|
||||||
const userInfo = useStore().user;
|
const userInfo = useStore().user;
|
||||||
const {data, send} = useRequest(getUserPermissions, {
|
|
||||||
immediate: false
|
|
||||||
});
|
|
||||||
const handleClick = () => {
|
|
||||||
|
|
||||||
const userId: string = userInfo.user.uid;
|
|
||||||
send(userId);
|
|
||||||
};
|
|
||||||
|
|
||||||
const wsOptions = {
|
const wsOptions = {
|
||||||
url: import.meta.env.VITE_WEB_SOCKET_URL + "?client_id=" + userInfo.user.uid,
|
url: import.meta.env.VITE_WEB_SOCKET_URL + "?client_id=" + userInfo.user.uid,
|
||||||
|
Reference in New Issue
Block a user