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 @@ - - - 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 @@ + + + + + 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 @@ + + + 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 @@ @@ -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); }; + +