From 96ae754efd65f081c9da78b201ad36b9f18c05a4 Mon Sep 17 00:00:00 2001
From: landaiqing <3517283258@qq.com>
Date: Thu, 26 Sep 2024 01:15:29 +0800
Subject: [PATCH] :art: updated comment code framework / add comment
verification
---
components.d.ts | 18 +-
src/api/captcha/index.ts | 13 +-
src/api/comment/index.ts | 44 +
src/components/CommentReply/CommentReply.vue | 879 ------------------
.../Components/CommentInput/CommentInput.vue | 248 +++++
.../Components/CommentInput/index.scss | 27 +
.../Components/CommentList/CommentList.vue | 325 +++++++
.../Components/CommentList/index.scss | 119 +++
.../Components/ReplyInput/ReplyInput.vue | 269 ++++++
.../Components/ReplyInput/index.scss | 52 ++
.../Components/ReplyList/ReplyList.vue | 233 +++++
.../Components/ReplyList/index.scss | 115 +++
.../Components/ReplyReplyInput/ReplyReply.vue | 273 ++++++
.../Components/ReplyReplyInput/index.scss | 52 ++
src/components/CommentReply/index.scss | 368 --------
src/components/CommentReply/index.vue | 22 +
src/locales/language/en.ts | 6 +
src/locales/language/zh.ts | 6 +
src/store/index.ts | 2 +
src/store/modules/commentStore.ts | 173 ++++
src/types/comment.d.ts | 4 +-
src/views/Main/MainPage.vue | 7 +-
22 files changed, 1997 insertions(+), 1258 deletions(-)
delete mode 100644 src/components/CommentReply/CommentReply.vue
create mode 100644 src/components/CommentReply/Components/CommentInput/CommentInput.vue
create mode 100644 src/components/CommentReply/Components/CommentInput/index.scss
create mode 100644 src/components/CommentReply/Components/CommentList/CommentList.vue
create mode 100644 src/components/CommentReply/Components/CommentList/index.scss
create mode 100644 src/components/CommentReply/Components/ReplyInput/ReplyInput.vue
create mode 100644 src/components/CommentReply/Components/ReplyInput/index.scss
create mode 100644 src/components/CommentReply/Components/ReplyList/ReplyList.vue
create mode 100644 src/components/CommentReply/Components/ReplyList/index.scss
create mode 100644 src/components/CommentReply/Components/ReplyReplyInput/ReplyReply.vue
create mode 100644 src/components/CommentReply/Components/ReplyReplyInput/index.scss
create mode 100644 src/components/CommentReply/index.vue
create mode 100644 src/store/modules/commentStore.ts
diff --git a/components.d.ts b/components.d.ts
index 798c8c1..e6c7b06 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -27,7 +27,6 @@ declare module 'vue' {
APagination: typeof import('ant-design-vue/es')['Pagination']
APopover: typeof import('ant-design-vue/es')['Popover']
AQrcode: typeof import('ant-design-vue/es')['QRCode']
- ASegmented: typeof import('ant-design-vue/es')['Segmented']
ASkeleton: typeof import('ant-design-vue/es')['Skeleton']
ASpin: typeof import('ant-design-vue/es')['Spin']
ATabPane: typeof import('ant-design-vue/es')['TabPane']
@@ -36,15 +35,17 @@ declare module 'vue' {
ATextarea: typeof import('ant-design-vue/es')['Textarea']
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
AUpload: typeof import('ant-design-vue/es')['Upload']
- BoxDog: typeof import('./src/components/BoxDog/BoxDog.vue')['default']
- Card3D: typeof import('./src/components/Card3D/Card3D.vue')['default']
+ BoxDog: typeof import('./src/Components/BoxDog/BoxDog.vue')['default']
+ Card3D: typeof import('./src/Components/Card3D/Card3D.vue')['default']
CloseCircleOutlined: typeof import('@ant-design/icons-vue')['CloseCircleOutlined']
- Clouds: typeof import('./src/components/Clouds/Clouds.vue')['default']
- CommentReply: typeof import('./src/components/CommentReply/CommentReply.vue')['default']
+ Clouds: typeof import('./src/Components/Clouds/Clouds.vue')['default']
+ CommentInput: typeof import('./src/Components/CommentReply/Components/CommentInput/CommentInput.vue')['default']
+ CommentList: typeof import('./src/Components/CommentReply/Components/CommentList/CommentList.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']
- EffectsCard: typeof import('./src/components/EffectsCard/EffectsCard.vue')['default']
+ DynamicTitle: typeof import('./src/Components/DynamicTitle/DynamicTitle.vue')['default']
+ EffectsCard: typeof import('./src/Components/EffectsCard/EffectsCard.vue')['default']
EyeOutlined: typeof import('@ant-design/icons-vue')['EyeOutlined']
ForgetPage: typeof import('./src/views/Forget/ForgetPage.vue')['default']
GithubOutlined: typeof import('@ant-design/icons-vue')['GithubOutlined']
@@ -57,6 +58,9 @@ declare module 'vue' {
QqOutlined: typeof import('@ant-design/icons-vue')['QqOutlined']
QRLogin: typeof import('./src/views/QRLogin/QRLogin.vue')['default']
QRLoginFooter: typeof import('./src/views/QRLogin/QRLoginFooter.vue')['default']
+ ReplyInput: typeof import('./src/Components/CommentReply/Components/ReplyInput/ReplyInput.vue')['default']
+ ReplyList: typeof import('./src/Components/CommentReply/Components/ReplyList/ReplyList.vue')['default']
+ ReplyReply: typeof import('./src/Components/CommentReply/Components/ReplyReplyInput/ReplyReply.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
SafetyOutlined: typeof import('@ant-design/icons-vue')['SafetyOutlined']
diff --git a/src/api/captcha/index.ts b/src/api/captcha/index.ts
index 9b9603d..0e04928 100644
--- a/src/api/captcha/index.ts
+++ b/src/api/captcha/index.ts
@@ -1,7 +1,7 @@
import {service} from "@/utils/alova/service.ts";
/**
- * 获取验证码图片数据
+ * 获取旋转验证码图片数据
*/
export const getRotatedCaptchaData = () => {
return service.Get('/api/captcha/rotate/get', {
@@ -29,3 +29,14 @@ export const checkRotatedCaptcha = (angle: any, key: any) => {
);
};
+/**
+ * 获取滑动验证码图片数据
+ */
+export const getSlideCaptchaDataApi = () => {
+ return service.Get('/api/captcha/slide/generate', {
+ meta: {
+ ignoreToken: false
+ },
+ });
+
+};
diff --git a/src/api/comment/index.ts b/src/api/comment/index.ts
index 12c7943..9c8c5df 100644
--- a/src/api/comment/index.ts
+++ b/src/api/comment/index.ts
@@ -11,6 +11,8 @@ export const commentSubmitApi = (params: any) => {
images: params.images,
topic_id: params.topic_id,
author: params.author,
+ point: params.point,
+ key: params.key,
},
{
name: 'comment-submit',
@@ -33,6 +35,8 @@ export const replySubmitApi = (params: any) => {
reply_id: params.reply_id,
reply_user: params.reply_user,
author: params.author,
+ point: params.point,
+ key: params.key,
},
{
name: 'reply-submit',
@@ -52,6 +56,8 @@ export const commentListApi = (params: any) => {
page: params.page,
size: params.size,
topic_id: params.topic_id,
+ user_id: params.user_id,
+ is_hot: params.is_hot,
},
{
cacheFor: {
@@ -75,6 +81,7 @@ export const replyListApi = (params: any) => {
size: params.size,
comment_id: params.comment_id,
topic_id: params.topic_id,
+ user_id: params.user_id,
},
{
cacheFor: {
@@ -104,6 +111,8 @@ export const replyReplySubmitApi = (params: any) => {
reply_id: params.reply_id,
reply_user: params.reply_user,
author: params.author,
+ point: params.point,
+ key: params.key,
},
{
name: 'reply-reply-submit',
@@ -113,3 +122,38 @@ export const replyReplySubmitApi = (params: any) => {
}
);
};
+/**
+ * @description 评论点赞
+ * @param params
+ */
+export const commentLikeApi = (params: any) => {
+ return service.Post('/api/auth/comment/like', {
+ user_id: params.user_id,
+ comment_id: params.comment_id,
+ topic_id: params.topic_id,
+ },
+ {
+ meta: {
+ ignoreToken: false,
+ },
+ }
+ );
+};
+
+/**
+ * @description 评论取消点赞
+ * @param params
+ */
+export const cancelCommentLikeApi = (params: any) => {
+ return service.Post('/api/auth/comment/cancel_like', {
+ user_id: params.user_id,
+ comment_id: params.comment_id,
+ topic_id: params.topic_id,
+ },
+ {
+ meta: {
+ ignoreToken: false,
+ },
+ }
+ );
+};
diff --git a/src/components/CommentReply/CommentReply.vue b/src/components/CommentReply/CommentReply.vue
deleted file mode 100644
index ea25e4c..0000000
--- a/src/components/CommentReply/CommentReply.vue
+++ /dev/null
@@ -1,879 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ item.nickname }}
- Lv.5
- UP
-
-
-
- {{ item.location }}
-
- {{ formatTimeAgo(item.created_time) }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ item.likes }}
-
-
-
-
- {{ item.dislikes }}
-
-
- {
- handleShowReplyComment(item.id);
- replyListThrottled(item.id)}" type="text" size="small"
- :icon="h(MessageOutlined)"
- class="reply-action-btn">
- {{ item.reply_count }}
-
-
- {{ t('comment.reply') }}
-
-
-
-
-
- {{ item.operating_system }}
-
-
- {{ item.browser }}
-
-
-
-
-
-
-
-
-
- {{ t('comment.report') }}
-
-
-
- {{ t('comment.copy') }}
-
-
-
- {{ t('comment.delete') }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ child.nickname }}
- @{{ child.reply_username }}
- Lv.5
-
-
-
-
- {{ child.location }}
-
- {{ formatTimeAgo(child.created_time) }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ child.likes }}
-
-
-
-
- {{ child.dislikes }}
-
-
-
- {{ t('comment.reply') }}
-
-
-
-
-
- {{ child.operating_system }}
-
-
- {{ child.browser }}
-
-
-
-
-
-
-
-
- {{ t('comment.report') }}
-
-
- {{ t('comment.copy') }}
-
-
- {{ t('comment.delete') }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/components/CommentReply/Components/CommentInput/CommentInput.vue b/src/components/CommentReply/Components/CommentInput/CommentInput.vue
new file mode 100644
index 0000000..3668eee
--- /dev/null
+++ b/src/components/CommentReply/Components/CommentInput/CommentInput.vue
@@ -0,0 +1,248 @@
+
+
+
+
+
+
+
diff --git a/src/components/CommentReply/Components/CommentInput/index.scss b/src/components/CommentReply/Components/CommentInput/index.scss
new file mode 100644
index 0000000..f70c4c7
--- /dev/null
+++ b/src/components/CommentReply/Components/CommentInput/index.scss
@@ -0,0 +1,27 @@
+
+.comment-content {
+ margin-left: 20px;
+
+ .comment-text {
+ width: 600px;
+ }
+
+ .comment-actions {
+ margin-top: 10px;
+
+ .comment-action-item {
+ cursor: pointer;
+ color: #767779;
+
+
+ .comment-action-icon {
+ font-size: 14px;
+ color: #767779;
+ }
+
+ .comment-action-icon:hover {
+ color: #08a327;
+ }
+ }
+ }
+}
diff --git a/src/components/CommentReply/Components/CommentList/CommentList.vue b/src/components/CommentReply/Components/CommentList/CommentList.vue
new file mode 100644
index 0000000..4193df1
--- /dev/null
+++ b/src/components/CommentReply/Components/CommentList/CommentList.vue
@@ -0,0 +1,325 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.nickname }}
+ Lv.5
+ UP
+
+
+
+ {{ item.location }}
+
+ {{ formatTimeAgo(item.created_time) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.likes }}
+
+
+ {{ item.likes }}
+
+
+ {
+ comment.handleShowCommentReply(item.id);
+ replyListThrottled(item.id)}" type="text" size="small"
+ :icon="h(MessageOutlined)"
+ class="reply-action-btn">
+ {{ item.reply_count }}
+
+
+ {{ t('comment.reply') }}
+
+
+
+
+
+ {{ item.operating_system }}
+
+
+ {{ item.browser }}
+
+
+
+
+
+
+
+
+
+ {{ t('comment.report') }}
+
+
+
+ {{ t('comment.copy') }}
+
+
+
+ {{ t('comment.delete') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/CommentReply/Components/CommentList/index.scss b/src/components/CommentReply/Components/CommentList/index.scss
new file mode 100644
index 0000000..6095bce
--- /dev/null
+++ b/src/components/CommentReply/Components/CommentList/index.scss
@@ -0,0 +1,119 @@
+.reply-header {
+ .reply-header-title {
+ font-size: 18px;
+ line-height: 30px;
+ font-weight: 600;
+ }
+}
+
+.reply-list {
+ margin-top: 30px;
+
+ .reply-pagination {
+ display: flex;
+ justify-content: flex-end;
+ margin-top: 10px;
+ }
+
+ .reply-content {
+ margin-left: 20px;
+
+ .reply-name {
+ font-size: 14px;
+ font-weight: 600;
+ cursor: pointer;
+ }
+
+ .reply-tag {
+ font-size: 10px;
+ font-weight: 800;
+ margin-left: 5px;
+ cursor: pointer;
+ }
+
+ .reply-ip {
+ font-size: 12px;
+ color: #767779;
+ }
+
+ .reply-time {
+ font-size: 12px;
+ color: #767779;
+ }
+
+ .reply-card {
+ width: 600px;
+ //margin-top: 5px;
+
+ .reply-images {
+ margin-top: 5px;
+ }
+
+ .reply-action-item {
+ margin-top: 10px;
+
+ .reply-action-btn {
+ font-size: 13px;
+ color: #767779;
+ cursor: pointer;
+
+ }
+
+ .reply-action-icon {
+ font-size: 14px;
+ color: #767779;
+ cursor: pointer;
+
+ }
+
+ .reply-action-icon:hover {
+ font-size: 14px;
+ color: #08a327;
+ cursor: pointer;
+
+ }
+
+ .reply-action-btn:hover {
+ font-size: 13px;
+ color: #08a327;
+ cursor: pointer;
+
+ }
+
+ .reply-action-icon-number {
+ font-size: 12px;
+ cursor: pointer;
+ color: #767779;
+ }
+ }
+
+ .reply-action-item-right {
+ margin-top: 10px;
+
+ .reply-action-btn {
+ font-size: 15px;
+ color: #767779;
+ cursor: pointer;
+ }
+
+ .reply-action-btn:hover {
+ font-size: 15px;
+ color: #08a327;
+ cursor: pointer;
+ }
+
+ .reply-action-info {
+ font-size: 10px;
+ color: #767779;
+ cursor: pointer;
+ }
+ }
+ }
+
+
+
+
+
+
+ }
+}
diff --git a/src/components/CommentReply/Components/ReplyInput/ReplyInput.vue b/src/components/CommentReply/Components/ReplyInput/ReplyInput.vue
new file mode 100644
index 0000000..a5321cd
--- /dev/null
+++ b/src/components/CommentReply/Components/ReplyInput/ReplyInput.vue
@@ -0,0 +1,269 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/CommentReply/Components/ReplyInput/index.scss b/src/components/CommentReply/Components/ReplyInput/index.scss
new file mode 100644
index 0000000..b8cbad7
--- /dev/null
+++ b/src/components/CommentReply/Components/ReplyInput/index.scss
@@ -0,0 +1,52 @@
+.reply-input-main {
+ margin-top: 5px;
+
+ .reply-input-title {
+ font-size: 13px;
+ color: #767779;
+ }
+
+ .reply-input-author {
+ font-size: 13px;
+ color: #767779;
+ }
+
+ .reply-input-cancel {
+ margin-left: 10px;
+ font-size: 13px;
+ color: #767779;
+ cursor: pointer;
+ }
+
+ .reply-input-content {
+ margin-top: 10px;
+
+ .reply-input-content-text {
+ margin-left: 10px;
+
+ .comment-text-reply {
+ width: 550px;
+ }
+
+ .comment-actions-reply {
+ margin-top: 5px;
+
+ .comment-action-item-reply {
+ cursor: pointer;
+ color: #767779;
+
+ .comment-action-icon-reply {
+ font-size: 14px;
+ color: #767779;
+ }
+
+ .comment-action-icon-reply:hover {
+ color: #08a327;
+ }
+ }
+ }
+ }
+ }
+
+
+}
diff --git a/src/components/CommentReply/Components/ReplyList/ReplyList.vue b/src/components/CommentReply/Components/ReplyList/ReplyList.vue
new file mode 100644
index 0000000..a5bf318
--- /dev/null
+++ b/src/components/CommentReply/Components/ReplyList/ReplyList.vue
@@ -0,0 +1,233 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ child.nickname }}
+ @{{ child.reply_username }}
+ Lv.5
+
+
+
+
+ {{ child.location }}
+
+ {{ formatTimeAgo(child.created_time) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ child.likes }}
+
+
+ {{ child.likes }}
+
+
+
+ {{ t('comment.reply') }}
+
+
+
+
+
+ {{ child.operating_system }}
+
+
+ {{ child.browser }}
+
+
+
+
+
+
+
+
+ {{ t('comment.report') }}
+
+
+ {{ t('comment.copy') }}
+
+
+ {{ t('comment.delete') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/CommentReply/Components/ReplyList/index.scss b/src/components/CommentReply/Components/ReplyList/index.scss
new file mode 100644
index 0000000..ecc48e3
--- /dev/null
+++ b/src/components/CommentReply/Components/ReplyList/index.scss
@@ -0,0 +1,115 @@
+.reply-item-child {
+ margin-top: 10px;
+ border-radius: 10px;
+ background-color: #f5f5f5;
+ padding: 10px;
+
+ .reply-pagination-child {
+ display: flex;
+ justify-content: flex-end;
+ margin-top: 10px;
+ }
+
+ .reply-item-child-content {
+ margin-left: 10px;
+
+ .reply-at {
+ font-size: 14px;
+ color: #767779;
+ cursor: pointer;
+ }
+
+ .reply-at:hover {
+ color: #25a9e3;
+ }
+
+ .reply-name-child {
+ font-size: 14px;
+ font-weight: 600;
+ cursor: pointer;
+ }
+
+ .reply-tag-child {
+ font-size: 10px;
+ font-weight: 800;
+ margin-left: 5px;
+ cursor: pointer;
+ }
+
+ .reply-ip-child {
+ font-size: 12px;
+ color: #767779;
+ }
+
+ .reply-time-child {
+ font-size: 12px;
+ color: #767779;
+ }
+
+ .reply-card-child {
+ width: 530px;
+
+ .reply-action-item-child {
+ margin-top: 10px;
+
+ .reply-action-btn-child {
+ font-size: 13px;
+ color: #767779;
+ cursor: pointer;
+ }
+
+ .reply-action-icon-child {
+ font-size: 14px;
+ color: #767779;
+ cursor: pointer;
+
+ }
+
+ .reply-action-icon-child:hover {
+ font-size: 14px;
+ color: #08a327;
+ cursor: pointer;
+
+ }
+
+ .reply-action-btn-child:hover {
+ font-size: 13px;
+ color: #08a327;
+ cursor: pointer;
+
+ }
+
+ .reply-action-icon-number-child {
+ font-size: 12px;
+ cursor: pointer;
+ color: #767779;
+ }
+
+ }
+
+ .reply-action-item-right-child {
+ margin-top: 10px;
+
+ .reply-action-btn-child {
+ font-size: 15px;
+ color: #767779;
+ cursor: pointer;
+ }
+
+ .reply-action-btn-child:hover {
+ font-size: 15px;
+ color: #08a327;
+ cursor: pointer;
+ }
+
+ .reply-action-info-child {
+ font-size: 10px;
+ color: #767779;
+ cursor: pointer;
+ }
+ }
+ }
+ }
+}
+
+
diff --git a/src/components/CommentReply/Components/ReplyReplyInput/ReplyReply.vue b/src/components/CommentReply/Components/ReplyReplyInput/ReplyReply.vue
new file mode 100644
index 0000000..52e9fc7
--- /dev/null
+++ b/src/components/CommentReply/Components/ReplyReplyInput/ReplyReply.vue
@@ -0,0 +1,273 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/CommentReply/Components/ReplyReplyInput/index.scss b/src/components/CommentReply/Components/ReplyReplyInput/index.scss
new file mode 100644
index 0000000..7161c44
--- /dev/null
+++ b/src/components/CommentReply/Components/ReplyReplyInput/index.scss
@@ -0,0 +1,52 @@
+.reply-input-main-child {
+ margin-top: 5px;
+
+ .reply-input-title-child {
+ font-size: 13px;
+ color: #767779;
+ }
+
+ .reply-input-author-child {
+ font-size: 13px;
+ color: #767779;
+ }
+
+ .reply-input-cancel-child {
+ margin-left: 10px;
+ font-size: 13px;
+ color: #767779;
+ cursor: pointer;
+ }
+
+ .reply-input-content-child {
+ margin-top: 10px;
+
+ .reply-input-content-text-child {
+ margin-left: 10px;
+
+ .comment-text-reply-child {
+ width: 480px;
+ }
+
+ .comment-actions-reply-child {
+ margin-top: 5px;
+
+ .comment-action-item-reply-child {
+ cursor: pointer;
+ color: #767779;
+
+ .comment-action-icon-reply-child {
+ font-size: 14px;
+ color: #767779;
+ }
+
+ .comment-action-icon-reply-child:hover {
+ color: #08a327;
+ }
+ }
+ }
+ }
+ }
+
+
+}
diff --git a/src/components/CommentReply/index.scss b/src/components/CommentReply/index.scss
index 360ebaa..6b4e596 100644
--- a/src/components/CommentReply/index.scss
+++ b/src/components/CommentReply/index.scss
@@ -13,376 +13,8 @@
margin-bottom: 10px;
}
- .comment-content {
- margin-left: 20px;
- .comment-text {
- width: 600px;
- }
- .comment-actions {
- margin-top: 10px;
- .comment-action-item {
- cursor: pointer;
- color: #767779;
-
-
- .comment-action-icon {
- font-size: 14px;
- color: #767779;
- }
-
- .comment-action-icon:hover {
- color: #08a327;
- }
- }
- }
- }
-
- .reply-header {
- .reply-header-title {
- font-size: 18px;
- line-height: 30px;
- font-weight: 600;
- }
-
- .reply-header-count {
- font-size: 12px;
- color: #767779;
- margin-top: 10px;
- }
-
- .reply-header-sort {
- margin-top: 10px;
- width: 100px;
- }
- }
-
- .reply-list {
- margin-top: 30px;
-
- .reply-pagination {
- display: flex;
- justify-content: flex-end;
- margin-top: 10px;
- }
-
- .reply-content {
- margin-left: 20px;
-
- .reply-name {
- font-size: 14px;
- font-weight: 600;
- cursor: pointer;
- }
-
- .reply-tag {
- font-size: 10px;
- font-weight: 800;
- margin-left: 5px;
- cursor: pointer;
- }
-
- .reply-ip {
- font-size: 12px;
- color: #767779;
- }
-
- .reply-time {
- font-size: 12px;
- color: #767779;
- }
-
- .reply-card {
- width: 600px;
- //margin-top: 5px;
-
- .reply-images {
- margin-top: 5px;
- }
-
- .reply-action-item {
- margin-top: 10px;
-
- .reply-action-btn {
- font-size: 13px;
- color: #767779;
- cursor: pointer;
-
- }
-
- .reply-action-icon {
- font-size: 14px;
- color: #767779;
- cursor: pointer;
-
- }
-
- .reply-action-icon:hover {
- font-size: 14px;
- color: #08a327;
- cursor: pointer;
-
- }
-
- .reply-action-btn:hover {
- font-size: 13px;
- color: #08a327;
- cursor: pointer;
-
- }
-
- .reply-action-icon-number {
- font-size: 12px;
- cursor: pointer;
- color: #767779;
- }
- }
-
- .reply-action-item-right {
- margin-top: 10px;
-
- .reply-action-btn {
- font-size: 15px;
- color: #767779;
- cursor: pointer;
- }
-
- .reply-action-btn:hover {
- font-size: 15px;
- color: #08a327;
- cursor: pointer;
- }
-
- .reply-action-info {
- font-size: 12px;
- color: #767779;
- cursor: pointer;
- }
- }
- }
-
- .reply-input-main {
- margin-top: 5px;
-
- .reply-input-title {
- font-size: 13px;
- color: #767779;
- }
-
- .reply-input-author {
- font-size: 13px;
- color: #767779;
- }
-
- .reply-input-cancel {
- margin-left: 10px;
- font-size: 13px;
- color: #767779;
- cursor: pointer;
- }
-
- .reply-input-content {
- margin-top: 10px;
-
- .reply-input-content-text {
- margin-left: 10px;
-
- .comment-text-reply {
- width: 550px;
- }
-
- .comment-actions-reply {
- margin-top: 5px;
-
- .comment-action-item-reply {
- cursor: pointer;
- color: #767779;
-
- .comment-action-icon-reply {
- font-size: 14px;
- color: #767779;
- }
-
- .comment-action-icon-reply:hover {
- color: #08a327;
- }
- }
- }
- }
- }
-
-
- }
-
- .reply-item-child {
- margin-top: 10px;
- border-radius: 10px;
- background-color: #f5f5f5;
- padding: 10px;
-
- .reply-pagination-child {
- display: flex;
- justify-content: flex-end;
- margin-top: 10px;
- }
-
- .reply-item-child-content {
- margin-left: 10px;
-
- .reply-at {
- font-size: 14px;
- color: #767779;
- cursor: pointer;
- }
-
- .reply-at:hover {
- color: #25a9e3;
- }
-
- .reply-name-child {
- font-size: 14px;
- font-weight: 600;
- cursor: pointer;
- }
-
- .reply-tag-child {
- font-size: 10px;
- font-weight: 800;
- margin-left: 5px;
- cursor: pointer;
- }
-
- .reply-ip-child {
- font-size: 12px;
- color: #767779;
- }
-
- .reply-time-child {
- font-size: 12px;
- color: #767779;
- }
-
- .reply-card-child {
- width: 530px;
-
- .reply-action-item-child {
- margin-top: 10px;
-
- .reply-action-btn-child {
- font-size: 13px;
- color: #767779;
- cursor: pointer;
- }
-
- .reply-action-icon-child {
- font-size: 14px;
- color: #767779;
- cursor: pointer;
-
- }
-
- .reply-action-icon-child:hover {
- font-size: 14px;
- color: #08a327;
- cursor: pointer;
-
- }
-
- .reply-action-btn-child:hover {
- font-size: 13px;
- color: #08a327;
- cursor: pointer;
-
- }
-
- .reply-action-icon-number-child {
- font-size: 12px;
- cursor: pointer;
- color: #767779;
- }
-
- }
-
- .reply-action-item-right-child {
- margin-top: 10px;
-
- .reply-action-btn-child {
- font-size: 15px;
- color: #767779;
- cursor: pointer;
- }
-
- .reply-action-btn-child:hover {
- font-size: 15px;
- color: #08a327;
- cursor: pointer;
- }
-
- .reply-action-info-child {
- font-size: 12px;
- color: #767779;
- cursor: pointer;
- }
- }
- }
- }
- }
-
- .reply-input-main-child {
- margin-top: 5px;
-
- .reply-input-title-child {
- font-size: 13px;
- color: #767779;
- }
-
- .reply-input-author-child {
- font-size: 13px;
- color: #767779;
- }
-
- .reply-input-cancel-child {
- margin-left: 10px;
- font-size: 13px;
- color: #767779;
- cursor: pointer;
- }
-
- .reply-input-content-child {
- margin-top: 10px;
-
- .reply-input-content-text-child {
- margin-left: 10px;
-
- .comment-text-reply-child {
- width: 480px;
- }
-
- .comment-actions-reply-child {
- margin-top: 5px;
-
- .comment-action-item-reply-child {
- cursor: pointer;
- color: #767779;
-
- .comment-action-icon-reply-child {
- font-size: 14px;
- color: #767779;
- }
-
- .comment-action-icon-reply-child:hover {
- color: #08a327;
- }
- }
- }
- }
- }
-
-
- }
- }
- }
}
diff --git a/src/components/CommentReply/index.vue b/src/components/CommentReply/index.vue
new file mode 100644
index 0000000..d3c9c90
--- /dev/null
+++ b/src/components/CommentReply/index.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
diff --git a/src/locales/language/en.ts b/src/locales/language/en.ts
index 233181b..3872002 100644
--- a/src/locales/language/en.ts
+++ b/src/locales/language/en.ts
@@ -94,5 +94,11 @@ export default {
delete: 'Delete',
copy: 'Copy',
cancelReply: 'Cancel Reply',
+ commentContentNotEmpty: 'Comment content cannot be empty!',
+ maxImageCount: 'Maximum image count reached!',
+ commentSuccess: 'comment success!',
+ commentError: 'comment failed!',
+ replySuccess: 'reply success!',
+ replyError: 'reply failed!',
}
};
diff --git a/src/locales/language/zh.ts b/src/locales/language/zh.ts
index 0d57149..b1d25ef 100644
--- a/src/locales/language/zh.ts
+++ b/src/locales/language/zh.ts
@@ -93,6 +93,12 @@ export default {
delete: '删除',
copy: '复制',
cancelReply: '取消',
+ commentContentNotEmpty: '评论内容不能为空!',
+ maxImageCount: '最多只能上传3张图片!',
+ commentSuccess: '评论成功!',
+ commentError: '评论失败!',
+ replySuccess: '回复成功!',
+ replyError: '回复失败!',
}
};
diff --git a/src/store/index.ts b/src/store/index.ts
index 29705dd..b364885 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -2,6 +2,7 @@ import {useAuthStore} from '@/store/modules/userStore.ts';
import {useThemeStore} from "@/store/modules/themeStore.ts";
import {langStore} from "@/store/modules/langStore.ts";
import {useClientStore} from "@/store/modules/clientStore.ts";
+import {useCommentStore} from "@/store/modules/commentStore.ts";
export default function useStore() {
return {
@@ -9,5 +10,6 @@ export default function useStore() {
theme: useThemeStore(),
lang: langStore(),
client: useClientStore(),
+ comment: useCommentStore(),
};
}
diff --git a/src/store/modules/commentStore.ts b/src/store/modules/commentStore.ts
new file mode 100644
index 0000000..71276f3
--- /dev/null
+++ b/src/store/modules/commentStore.ts
@@ -0,0 +1,173 @@
+import {defineStore} from "pinia";
+import {reactive, ref} from "vue";
+import {Comment} from "@/types/comment";
+import {cancelCommentLikeApi, commentLikeApi, commentListApi, replyListApi} from "@/api/comment";
+import {message} from "ant-design-vue";
+import {getSlideCaptchaDataApi} from "@/api/captcha";
+
+
+export const useCommentStore = defineStore(
+ 'comment',
+ () => {
+ const commentList = ref({} as Comment);
+ const commentLoading = ref(true);
+ const replyLoading = ref(true);
+ const showReplyInput = ref(null);
+ const showCommentReply = ref(null);
+ const replyList = ref({} as Comment);
+ const commentMap = reactive({});
+ const slideCaptchaData = reactive({
+ key: "",
+ image: "",
+ thumb: "",
+ thumbWidth: 0,
+ thumbHeight: 0,
+ thumbX: 0,
+ thumbY: 0
+ });
+
+ /**
+ * 获取评论列表
+ * @param params
+ */
+ async function getCommentList(params: any) {
+ const data: any = {
+ user_id: params.user_id,
+ topic_id: params.topic_id,
+ page: params.page,
+ size: params.size,
+ is_hot: params.is_hot,
+ };
+ commentLoading.value = true;
+ commentList.value = {} as Comment;
+ // 获取评论列表
+ const result: any = await commentListApi(data);
+ if (result.code === 200 && result.success && result.data) {
+ commentList.value = result.data;
+ commentLoading.value = false;
+ commentList.value.comments.forEach((item: any) => {
+ commentMap[item.id] = item;
+ });
+ }
+ }
+
+ /**
+ * 显示回复输入框
+ */
+ const handleShowReplyInput = (index: any) => {
+ showReplyInput.value = showReplyInput.value === index ? null : index;
+ };
+ /**
+ * 关闭回复输入框
+ */
+ const closeReplyInput = () => {
+ showReplyInput.value = null;
+ };
+ /**
+ * 是否显示回复
+ */
+ const handleShowCommentReply = (index: any) => {
+ showCommentReply.value = showCommentReply.value === index ? null : index;
+ };
+
+ /**
+ * 获取回复列表
+ * @param data
+ */
+ async function getReplyList(data: any) {
+ const params: any = {
+ topic_id: data.topic_id,
+ page: data.page,
+ size: data.size,
+ comment_id: data.comment_id,
+ user_id: data.user_id,
+ };
+ replyLoading.value = true;
+ replyList.value = {} as Comment;
+ // 获取评论列表
+ const result: any = await replyListApi(params);
+ if (result.code === 200 && result.success && result.data) {
+ replyList.value = result.data;
+ replyLoading.value = false;
+ }
+ }
+
+ /**
+ * 评论点赞
+ * @param data
+ */
+ async function commentLike(data: any): Promise {
+ const params: any = {
+ comment_id: data.comment_id,
+ user_id: data.user_id,
+ topic_id: data.topic_id,
+ };
+ const result: any = await commentLikeApi(params);
+ if (result.code !== 200 || !result.success) {
+ message.error(result.message);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * 取消评论点赞
+ * @param data
+ */
+ async function cancelCommentLike(data: any): Promise {
+ const params: any = {
+ comment_id: data.comment_id,
+ user_id: data.user_id,
+ topic_id: data.topic_id,
+ };
+ const result: any = await cancelCommentLikeApi(params);
+ if (result.code !== 200 || !result.success) {
+ message.error(result.message);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * 获取滑动验证码数据
+ */
+ async function getSlideCaptchaData(): Promise {
+ const res: any = await getSlideCaptchaDataApi();
+ if (res.code == 200 && res.data) {
+ const {key, image, thumb, thumb_width, thumb_height, thumb_x, thumb_y} = res.data;
+ slideCaptchaData.key = key;
+ slideCaptchaData.image = image;
+ slideCaptchaData.thumb = thumb;
+ slideCaptchaData.thumbWidth = thumb_width;
+ slideCaptchaData.thumbHeight = thumb_height;
+ slideCaptchaData.thumbX = thumb_x;
+ slideCaptchaData.thumbY = thumb_y;
+ return true;
+ }
+ return false;
+ }
+
+ return {
+ commentList,
+ commentLoading,
+ showReplyInput,
+ showCommentReply,
+ replyList,
+ replyLoading,
+ slideCaptchaData,
+ commentMap,
+ getCommentList,
+ handleShowReplyInput,
+ closeReplyInput,
+ handleShowCommentReply,
+ getReplyList,
+ commentLike,
+ cancelCommentLike,
+ getSlideCaptchaData,
+ };
+ },
+ {
+ // 开启数据持久化
+ persist: false,
+ }
+);
diff --git a/src/types/comment.d.ts b/src/types/comment.d.ts
index 468fad8..2da6833 100644
--- a/src/types/comment.d.ts
+++ b/src/types/comment.d.ts
@@ -10,7 +10,6 @@ interface CommentContent {
browser: string;
content: string;
created_time: string;
- dislikes: number;
id: number;
likes: number;
location: string;
@@ -25,6 +24,7 @@ interface CommentContent {
nickname: string;
level?: number;
images: string[];
+ is_liked: boolean;
}
export interface ReplyCommentParams {
@@ -36,4 +36,6 @@ export interface ReplyCommentParams {
reply_id: number,
reply_user: string,
reply_to: number,
+ point: [number, number]
+ key: string
}
diff --git a/src/views/Main/MainPage.vue b/src/views/Main/MainPage.vue
index 7c199f7..d227675 100644
--- a/src/views/Main/MainPage.vue
+++ b/src/views/Main/MainPage.vue
@@ -1,8 +1,8 @@
-
Welcome to Main Page
获取登录用户角色
{{ data }}
+
@@ -10,7 +10,8 @@
import {useRequest} from "alova/client";
import {getUserPermissions} from "@/api/user";
import useStore from "@/store";
-import CommentReply from "@/components/CommentReply/CommentReply.vue";
+import CommentReply from "@/components/CommentReply/index.vue";
+
const {data, send} = useRequest(getUserPermissions, {
immediate: false
@@ -20,6 +21,8 @@ const handleClick = () => {
const userId: string = userInfo.user.uid;
send(userId);
};
+
+