@jx3box/jx3box-vue3-ui 0.6.8 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/css/quick-reply.less +56 -0
- package/assets/data/reply_template.json +6 -0
- package/assets/img/comment.svg +1 -0
- package/assets/img/heart_1.svg +1 -0
- package/assets/img/heart_2.svg +1 -0
- package/assets/img/hide.svg +1 -0
- package/assets/img/view.svg +1 -0
- package/package.json +3 -3
- package/src/App.vue +2 -2
- package/src/comment/CommentContent.vue +221 -68
- package/src/comment/CommentContentSimple.vue +85 -5
- package/src/comment/CommentInputForm.vue +32 -2
- package/src/comment/CommentWithReply.vue +40 -9
- package/src/comment/QuickReply.vue +64 -0
- package/src/comment/ReplyForReply.vue +8 -8
- package/src/comment/ReplyItem.vue +13 -2
- package/src/comment/ReplyList.vue +10 -2
- package/src/single/Comment.vue +109 -13
- package/utils/emotion.js +19 -8
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
.c-jx3box-reply {
|
|
2
|
+
.u-reference {
|
|
3
|
+
cursor: pointer;
|
|
4
|
+
position: relative;
|
|
5
|
+
top: 8px;
|
|
6
|
+
margin-left: 10px;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
.c-jx3box-reply-pop {
|
|
10
|
+
padding: 0;
|
|
11
|
+
width: 280px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.c-jx3box-reply-pop__content {
|
|
15
|
+
position: relative;
|
|
16
|
+
|
|
17
|
+
.u-title {
|
|
18
|
+
font-size: 14px;
|
|
19
|
+
padding: 10px;
|
|
20
|
+
}
|
|
21
|
+
.u-close {
|
|
22
|
+
position: absolute;
|
|
23
|
+
top: 10px;
|
|
24
|
+
right: 10px;
|
|
25
|
+
cursor: pointer;
|
|
26
|
+
font-size: 16px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.m-reply-list {
|
|
30
|
+
padding: 0 10px 10px 10px;
|
|
31
|
+
max-height: 300px;
|
|
32
|
+
overflow-y: auto;
|
|
33
|
+
}
|
|
34
|
+
.m-reply-list__item {
|
|
35
|
+
cursor: pointer;
|
|
36
|
+
padding: 5px;
|
|
37
|
+
border: 1px solid #eee;
|
|
38
|
+
border-radius: 4px;
|
|
39
|
+
margin-bottom: 5px;
|
|
40
|
+
.u-name {
|
|
41
|
+
font-size: 12px;
|
|
42
|
+
color: #999;
|
|
43
|
+
}
|
|
44
|
+
.u-content {
|
|
45
|
+
font-size: 14px;
|
|
46
|
+
margin-top: 5px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&:hover {
|
|
50
|
+
color: #fff;
|
|
51
|
+
background-color: #409eff;
|
|
52
|
+
border-color: #409eff;
|
|
53
|
+
transition: all 0.3s;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?><svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M44 6H4V36H13V41L23 36H44V6Z" fill="none" stroke="#666" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path d="M14 19.5V22.5" stroke="#666" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path d="M24 19.5V22.5" stroke="#666" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path d="M34 19.5V22.5" stroke="#666" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg id="Layer_1" height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg" data-name="Layer 1"><path fill="#0366d6" d="m256 436a54.62 54.62 0 0 1 -29.53-8.64c-25-16.07-73.08-49.05-113.75-89.32-49.91-49.46-75.22-96.04-75.22-138.48 0-29.49 8.72-56.51 25.22-78.13a115.2 115.2 0 0 1 137.89-35.75c21.18 9.14 40.07 24.55 55.39 45 15.32-20.5 34.21-35.91 55.39-45a115.2 115.2 0 0 1 137.89 35.75c16.5 21.62 25.22 48.64 25.22 78.13 0 42.44-25.31 89-75.22 138.44-40.67 40.27-88.73 73.25-113.75 89.32a54.62 54.62 0 0 1 -29.53 8.68zm-101.84-334.94a89.41 89.41 0 0 0 -23.42 3.1 90.93 90.93 0 0 0 -48.15 32.44c-13.14 17.22-20.09 39-20.09 63 0 35.52 22.81 76.12 67.81 120.68 39 38.66 85.47 70.5 109.67 86a29.72 29.72 0 0 0 32 0c24.2-15.54 70.63-47.38 109.67-86 45-44.56 67.81-85.16 67.81-120.68 0-24-6.95-45.74-20.09-63a90.93 90.93 0 0 0 -48.15-32.44c-34.17-9.28-82.18.42-114.48 55.48a12.49 12.49 0 0 1 -21.56 0c-25.38-43.34-60.54-58.58-91.02-58.58z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg id="Layer_1" height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg" data-name="Layer 1"><path d="m449.28 121.43a115.2 115.2 0 0 0 -137.89-35.75c-21.18 9.14-40.07 24.55-55.39 45-15.32-20.5-34.21-35.91-55.39-45a115.2 115.2 0 0 0 -137.89 35.75c-16.5 21.62-25.22 48.64-25.22 78.13 0 42.44 25.31 89 75.22 138.44 40.67 40.27 88.73 73.25 113.75 89.32a54.78 54.78 0 0 0 59.06 0c25-16.07 73.08-49.05 113.75-89.32 49.91-49.42 75.22-96 75.22-138.44 0-29.49-8.72-56.51-25.22-78.13z" fill="#f9595f"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" data-v-ea893728=""><path fill="#0366d6" d="M876.8 156.8c0-9.6-3.2-16-9.6-22.4-6.4-6.4-12.8-9.6-22.4-9.6-9.6 0-16 3.2-22.4 9.6L736 220.8c-64-32-137.6-51.2-224-60.8-160 16-288 73.6-377.6 176C44.8 438.4 0 496 0 512s48 73.6 134.4 176c22.4 25.6 44.8 48 73.6 67.2l-86.4 89.6c-6.4 6.4-9.6 12.8-9.6 22.4 0 9.6 3.2 16 9.6 22.4 6.4 6.4 12.8 9.6 22.4 9.6 9.6 0 16-3.2 22.4-9.6l704-710.4c3.2-6.4 6.4-12.8 6.4-22.4Zm-646.4 528c-76.8-70.4-128-128-153.6-172.8 28.8-48 80-105.6 153.6-172.8C304 272 400 230.4 512 224c64 3.2 124.8 19.2 176 44.8l-54.4 54.4C598.4 300.8 560 288 512 288c-64 0-115.2 22.4-160 64s-64 96-64 160c0 48 12.8 89.6 35.2 124.8L256 707.2c-9.6-6.4-19.2-16-25.6-22.4Zm140.8-96c-12.8-22.4-19.2-48-19.2-76.8 0-44.8 16-83.2 48-112 32-28.8 67.2-48 112-48 28.8 0 54.4 6.4 73.6 19.2zM889.599 336c-12.8-16-28.8-28.8-41.6-41.6l-48 48c73.6 67.2 124.8 124.8 150.4 169.6-28.8 48-80 105.6-153.6 172.8-73.6 67.2-172.8 108.8-284.8 115.2-51.2-3.2-99.2-12.8-140.8-28.8l-48 48c57.6 22.4 118.4 38.4 188.8 44.8 160-16 288-73.6 377.6-176C979.199 585.6 1024 528 1024 512s-48.001-73.6-134.401-176Z"></path><path fill="#0366d6" d="M511.998 672c-12.8 0-25.6-3.2-38.4-6.4l-51.2 51.2c28.8 12.8 57.6 19.2 89.6 19.2 64 0 115.2-22.4 160-64 41.6-41.6 64-96 64-160 0-32-6.4-64-19.2-89.6l-51.2 51.2c3.2 12.8 6.4 25.6 6.4 38.4 0 44.8-16 83.2-48 112-32 28.8-67.2 48-112 48Z"></path></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" data-v-ea893728=""><path fill="#0366d6" d="M512 160c320 0 512 352 512 352S832 864 512 864 0 512 0 512s192-352 512-352m0 64c-225.28 0-384.128 208.064-436.8 288 52.608 79.872 211.456 288 436.8 288 225.28 0 384.128-208.064 436.8-288-52.608-79.872-211.456-288-436.8-288zm0 64a224 224 0 1 1 0 448 224 224 0 0 1 0-448m0 64a160.192 160.192 0 0 0-160 160c0 88.192 71.744 160 160 160s160-71.808 160-160-71.744-160-160-160"></path></svg>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jx3box/jx3box-vue3-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "JX3BOX Vue3 UI",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@element-plus/icons-vue": "^2.1.0",
|
|
29
|
-
"@jx3box/jx3box-common": "^8.2.
|
|
30
|
-
"@jx3box/jx3box-data": "^3.5.
|
|
29
|
+
"@jx3box/jx3box-common": "^8.2.9",
|
|
30
|
+
"@jx3box/jx3box-data": "^3.5.8",
|
|
31
31
|
"@jx3box/jx3box-emotion": "^1.2.6",
|
|
32
32
|
"@jx3box/jx3box-macro": "^1.0.1",
|
|
33
33
|
"@jx3box/jx3box-talent": "^1.2.7",
|
package/src/App.vue
CHANGED
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
:postId="57260"
|
|
68
68
|
:allowGift="true"
|
|
69
69
|
/>
|
|
70
|
-
<Comment category="post" id="
|
|
70
|
+
<Comment category="post" id="54842"></Comment>
|
|
71
71
|
<RightSidebar :show-toggle="true">
|
|
72
72
|
<PostTopic type="bps" :id="48857"></PostTopic>
|
|
73
73
|
<div id="directory"></div>
|
|
@@ -109,7 +109,7 @@ export default {
|
|
|
109
109
|
},
|
|
110
110
|
data() {
|
|
111
111
|
return {
|
|
112
|
-
post_id: "
|
|
112
|
+
post_id: "54842",
|
|
113
113
|
post: "",
|
|
114
114
|
client: location.href.includes("origin") ? "origin" : "std",
|
|
115
115
|
tag: "",
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<div
|
|
4
4
|
class="u-text"
|
|
5
5
|
v-if="content != ''"
|
|
6
|
-
v-html="
|
|
6
|
+
v-html="renderContent"
|
|
7
7
|
></div>
|
|
8
8
|
<div class="u-attachements" v-if="attachments.length">
|
|
9
9
|
<el-image
|
|
@@ -14,70 +14,136 @@
|
|
|
14
14
|
lazy
|
|
15
15
|
></el-image>
|
|
16
16
|
</div>
|
|
17
|
-
<div class="u-toolbar">
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
17
|
+
<div class="u-toolbar u-toolbar--primary">
|
|
18
|
+
<div class="u-toolbar-left">
|
|
19
|
+
<el-button
|
|
20
|
+
class="u-admin"
|
|
21
|
+
v-if="!currentUserHadLike"
|
|
22
|
+
type="text"
|
|
23
|
+
size="small"
|
|
24
|
+
@click="doLike(true)"
|
|
25
|
+
><img
|
|
26
|
+
class="u-up"
|
|
27
|
+
src="../../assets/img/heart_1.svg"
|
|
28
|
+
alt=""
|
|
29
|
+
/>点赞<span class="u-like-count">{{ likesFormat(hasLikeCount) }}</span></el-button
|
|
30
|
+
>
|
|
31
|
+
<el-button
|
|
32
|
+
class="u-admin"
|
|
33
|
+
type="text"
|
|
34
|
+
size="small"
|
|
35
|
+
v-if="currentUserHadLike"
|
|
36
|
+
@click="doLike(false)"
|
|
37
|
+
><img
|
|
38
|
+
class="u-up"
|
|
39
|
+
src="../../assets/img/heart_2.svg"
|
|
40
|
+
alt=""
|
|
41
|
+
/>已赞<span class="u-like-count">{{
|
|
42
|
+
likesFormat(hasLikeCount)
|
|
43
|
+
}}</span></el-button
|
|
44
|
+
>
|
|
45
|
+
<el-button
|
|
46
|
+
class="u-admin"
|
|
47
|
+
link
|
|
48
|
+
size="small"
|
|
49
|
+
icon="ChatRound"
|
|
50
|
+
@click="showForm = !showForm"
|
|
51
|
+
type="primary"
|
|
52
|
+
>回复</el-button
|
|
53
|
+
>
|
|
54
|
+
<el-button
|
|
55
|
+
class="u-admin"
|
|
56
|
+
v-if="canDelete"
|
|
57
|
+
link
|
|
58
|
+
icon="Delete"
|
|
59
|
+
size="small"
|
|
60
|
+
@click="deleteComment()"
|
|
61
|
+
type="danger"
|
|
62
|
+
>删除</el-button
|
|
63
|
+
>
|
|
64
|
+
<el-button
|
|
65
|
+
class="u-admin"
|
|
66
|
+
type="text"
|
|
67
|
+
size="small"
|
|
68
|
+
icon="Delete"
|
|
69
|
+
v-if="canHide"
|
|
70
|
+
@click="hideComment()"
|
|
71
|
+
title="拉入黑洞后,仅评论者自己独自可见"
|
|
72
|
+
>黑洞</el-button
|
|
73
|
+
>
|
|
74
|
+
<el-button
|
|
75
|
+
class="u-admin"
|
|
76
|
+
v-if="canSetTop"
|
|
77
|
+
link
|
|
78
|
+
icon="Top"
|
|
79
|
+
size="small"
|
|
80
|
+
@click="topComment(true)"
|
|
81
|
+
type="primary"
|
|
82
|
+
>置顶</el-button
|
|
83
|
+
>
|
|
84
|
+
<el-button
|
|
85
|
+
class="u-admin"
|
|
86
|
+
v-if="canCancelTop"
|
|
87
|
+
link
|
|
88
|
+
icon="Top"
|
|
89
|
+
size="small"
|
|
90
|
+
@click="topComment(false)"
|
|
91
|
+
type="primary"
|
|
92
|
+
>取消置顶</el-button
|
|
93
|
+
>
|
|
94
|
+
<el-button
|
|
95
|
+
class="u-admin"
|
|
96
|
+
v-if="canSetStar"
|
|
97
|
+
link
|
|
98
|
+
icon="Star"
|
|
99
|
+
size="small"
|
|
100
|
+
@click="starComment(true)"
|
|
101
|
+
type="primary"
|
|
102
|
+
>加精</el-button
|
|
103
|
+
>
|
|
104
|
+
<el-button
|
|
105
|
+
class="u-admin"
|
|
106
|
+
v-if="canCancelStar"
|
|
107
|
+
link
|
|
108
|
+
icon="StarFilled"
|
|
109
|
+
size="small"
|
|
110
|
+
@click="starComment(false)"
|
|
111
|
+
type="primary"
|
|
112
|
+
>取消加精</el-button
|
|
113
|
+
>
|
|
114
|
+
<time class="u-date">
|
|
115
|
+
<i class="Clock"></i>
|
|
116
|
+
{{ dataFormat(date) }}
|
|
117
|
+
</time>
|
|
118
|
+
</div>
|
|
119
|
+
<div class="u-toolbar-right">
|
|
120
|
+
<el-button
|
|
121
|
+
class="u-admin u-filter"
|
|
122
|
+
v-if="canAddWhite"
|
|
123
|
+
type="text"
|
|
124
|
+
size="small"
|
|
125
|
+
@click="setWhiteComment(true)"
|
|
126
|
+
>
|
|
127
|
+
<img
|
|
128
|
+
class="u-icon-filter"
|
|
129
|
+
src="../../assets/img/view.svg"
|
|
130
|
+
alt="显示"
|
|
131
|
+
/>
|
|
132
|
+
显示</el-button
|
|
133
|
+
>
|
|
134
|
+
<el-button
|
|
135
|
+
class="u-admin u-filter"
|
|
136
|
+
v-if="canRemoveWhite"
|
|
137
|
+
type="text"
|
|
138
|
+
size="small"
|
|
139
|
+
@click="setWhiteComment(false)"
|
|
140
|
+
><img
|
|
141
|
+
class="u-icon-filter"
|
|
142
|
+
src="../../assets/img/hide.svg"
|
|
143
|
+
alt="隐藏"
|
|
144
|
+
/>隐藏</el-button
|
|
145
|
+
>
|
|
146
|
+
</div>
|
|
81
147
|
</div>
|
|
82
148
|
<el-form
|
|
83
149
|
v-if="showForm"
|
|
@@ -137,16 +203,21 @@ function fillZero(num) {
|
|
|
137
203
|
}
|
|
138
204
|
export default {
|
|
139
205
|
props: [
|
|
140
|
-
|
|
206
|
+
"content",
|
|
141
207
|
"date",
|
|
142
208
|
"hasReply",
|
|
143
209
|
"canDelete",
|
|
144
210
|
"canSetTop",
|
|
145
211
|
"canCancelTop",
|
|
212
|
+
"canHide",
|
|
213
|
+
"isLike", // 是否已点赞
|
|
214
|
+
"likes", // 点赞数
|
|
146
215
|
"canSetStar",
|
|
147
216
|
"canCancelStar",
|
|
148
217
|
"attachments",
|
|
149
218
|
"commentId",
|
|
219
|
+
"canAddWhite", // 是否可以添加到过滤白名单, 因为对于一般用户,它看不到非白名单的评论,所以“可以添加到白名单”的权限不要在加一次用户层面的权限判定
|
|
220
|
+
"canRemoveWhite", // 是否可以从过滤白名单移除
|
|
150
221
|
],
|
|
151
222
|
components: {
|
|
152
223
|
Uploader,
|
|
@@ -162,6 +233,10 @@ export default {
|
|
|
162
233
|
showUploader: false,
|
|
163
234
|
inputId: "",
|
|
164
235
|
previewList: [],
|
|
236
|
+
currentUserHadLike: this.isLike,
|
|
237
|
+
hasLikeCount: this.likes,
|
|
238
|
+
|
|
239
|
+
renderContent: "",
|
|
165
240
|
};
|
|
166
241
|
},
|
|
167
242
|
mounted() {
|
|
@@ -174,13 +249,34 @@ export default {
|
|
|
174
249
|
});
|
|
175
250
|
},
|
|
176
251
|
},
|
|
252
|
+
watch: {
|
|
253
|
+
content: {
|
|
254
|
+
handler: function (val) {
|
|
255
|
+
this.formatContent(val);
|
|
256
|
+
},
|
|
257
|
+
immediate: true,
|
|
258
|
+
},
|
|
259
|
+
},
|
|
177
260
|
methods: {
|
|
261
|
+
doLike(setLike) {
|
|
262
|
+
if (setLike === this.currentUserHadLike) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
this.currentUserHadLike = setLike;
|
|
266
|
+
this.hasLikeCount = setLike
|
|
267
|
+
? this.hasLikeCount + 1
|
|
268
|
+
: this.hasLikeCount - 1;
|
|
269
|
+
this.$emit("setLikeComment", setLike);
|
|
270
|
+
},
|
|
178
271
|
topComment(setTop) {
|
|
179
272
|
this.$emit("setTopComment", setTop);
|
|
180
273
|
},
|
|
181
274
|
starComment(setStar) {
|
|
182
275
|
this.$emit("setStarComment", setStar);
|
|
183
276
|
},
|
|
277
|
+
setWhiteComment(white) {
|
|
278
|
+
this.$emit("setWhiteComment", white);
|
|
279
|
+
},
|
|
184
280
|
deleteComment() {
|
|
185
281
|
this.$confirm("确定删除该评论吗?", "提示", {
|
|
186
282
|
confirmButtonText: "确定",
|
|
@@ -192,6 +288,17 @@ export default {
|
|
|
192
288
|
})
|
|
193
289
|
.catch(() => {});
|
|
194
290
|
},
|
|
291
|
+
hideComment() {
|
|
292
|
+
this.$confirm("确定隐藏该评论吗?", "提示", {
|
|
293
|
+
confirmButtonText: "确定",
|
|
294
|
+
cancelButtonText: "取消",
|
|
295
|
+
type: "warning",
|
|
296
|
+
})
|
|
297
|
+
.then(() => {
|
|
298
|
+
this.$emit("hide", this.commentId);
|
|
299
|
+
})
|
|
300
|
+
.catch(() => {});
|
|
301
|
+
},
|
|
195
302
|
dataFormat(str) {
|
|
196
303
|
let d = new Date(str);
|
|
197
304
|
return (
|
|
@@ -208,7 +315,9 @@ export default {
|
|
|
208
315
|
fillZero(d.getSeconds())
|
|
209
316
|
);
|
|
210
317
|
},
|
|
211
|
-
|
|
318
|
+
likesFormat(count) {
|
|
319
|
+
return count > 0 ? count : "";
|
|
320
|
+
},
|
|
212
321
|
attachmentUploadFinish(data) {
|
|
213
322
|
this.disableSubmitBtn = false;
|
|
214
323
|
this.$emit("addNewReply", {
|
|
@@ -233,7 +342,9 @@ export default {
|
|
|
233
342
|
}
|
|
234
343
|
},
|
|
235
344
|
hideForm() {},
|
|
236
|
-
formatContent
|
|
345
|
+
async formatContent(str) {
|
|
346
|
+
this.renderContent = await formatContent(str);
|
|
347
|
+
},
|
|
237
348
|
async handleEmotionSelected(emotionVal) {
|
|
238
349
|
const myField = document.querySelector(`#id${this.inputId}`);
|
|
239
350
|
const value = emotionVal.key;
|
|
@@ -273,9 +384,29 @@ export default {
|
|
|
273
384
|
position: relative;
|
|
274
385
|
.u-toolbar {
|
|
275
386
|
font-size: 12px;
|
|
387
|
+
|
|
276
388
|
.el-button + .el-button {
|
|
277
389
|
margin-left: 20px;
|
|
278
390
|
}
|
|
391
|
+
|
|
392
|
+
&.u-toolbar--primary {
|
|
393
|
+
display: flex;
|
|
394
|
+
justify-content: space-between;
|
|
395
|
+
|
|
396
|
+
.u-toolbar-right {
|
|
397
|
+
padding-right: 5px;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.u-filter span {
|
|
402
|
+
display: flex;
|
|
403
|
+
align-items: center;
|
|
404
|
+
gap: 5px;
|
|
405
|
+
}
|
|
406
|
+
.u-icon-filter {
|
|
407
|
+
width: 16px;
|
|
408
|
+
height: 16px;
|
|
409
|
+
}
|
|
279
410
|
}
|
|
280
411
|
.u-date {
|
|
281
412
|
color: #c0c4cc;
|
|
@@ -286,6 +417,7 @@ export default {
|
|
|
286
417
|
}
|
|
287
418
|
.u-cmt {
|
|
288
419
|
padding: 5px 0 10px 0;
|
|
420
|
+
position: relative;
|
|
289
421
|
.u-text {
|
|
290
422
|
line-height: 1.715;
|
|
291
423
|
img {
|
|
@@ -303,12 +435,33 @@ export default {
|
|
|
303
435
|
}
|
|
304
436
|
}
|
|
305
437
|
}
|
|
438
|
+
.u-up {
|
|
439
|
+
width: 12px;
|
|
440
|
+
height: 12px;
|
|
441
|
+
position: relative;
|
|
442
|
+
top: 1px;
|
|
443
|
+
margin-right: 5px;
|
|
444
|
+
}
|
|
445
|
+
.u-like-count {
|
|
446
|
+
margin-left: 3px;
|
|
447
|
+
// &:before {
|
|
448
|
+
// content: "(";
|
|
449
|
+
// }
|
|
450
|
+
// &:after {
|
|
451
|
+
// content: ")";
|
|
452
|
+
// }
|
|
453
|
+
color: #999;
|
|
454
|
+
}
|
|
306
455
|
}
|
|
307
456
|
@media screen and (max-width: 767px) {
|
|
308
457
|
.c-comment-cmt {
|
|
309
458
|
.u-toolbar {
|
|
310
459
|
position: static;
|
|
311
460
|
margin-top: 10px;
|
|
461
|
+
|
|
462
|
+
&.u-toolbar--primary {
|
|
463
|
+
display: block !important;
|
|
464
|
+
}
|
|
312
465
|
}
|
|
313
466
|
}
|
|
314
467
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
>
|
|
9
9
|
:
|
|
10
10
|
</span>
|
|
11
|
-
<div class="u-reply-text" v-html="
|
|
11
|
+
<div class="u-reply-text" v-html="renderContent"></div>
|
|
12
12
|
<!--<div class="u-reply-text" v-html="content"></div>-->
|
|
13
13
|
<!-- <p v-for="(p, index) in getPList(content)" :key="index" v-html="formatContent(p)"></p> -->
|
|
14
14
|
</div>
|
|
@@ -22,13 +22,41 @@
|
|
|
22
22
|
></el-image>
|
|
23
23
|
</div>
|
|
24
24
|
<div class="u-toolbar">
|
|
25
|
+
<el-button
|
|
26
|
+
class="u-admin"
|
|
27
|
+
v-if="!currentUserHadLike"
|
|
28
|
+
type="text"
|
|
29
|
+
size="mini"
|
|
30
|
+
@click="doLike(true)"
|
|
31
|
+
><img
|
|
32
|
+
class="u-up"
|
|
33
|
+
src="../../assets/img/heart_1.svg"
|
|
34
|
+
alt=""
|
|
35
|
+
/>点赞<span class="u-like-count">{{
|
|
36
|
+
likesFormat(hasLikeCount)
|
|
37
|
+
}}</span></el-button
|
|
38
|
+
>
|
|
39
|
+
<el-button
|
|
40
|
+
class="u-admin"
|
|
41
|
+
type="text"
|
|
42
|
+
size="mini"
|
|
43
|
+
v-if="currentUserHadLike"
|
|
44
|
+
@click="doLike(false)"
|
|
45
|
+
><img
|
|
46
|
+
class="u-up"
|
|
47
|
+
src="../../assets/img/heart_2.svg"
|
|
48
|
+
alt=""
|
|
49
|
+
/>已赞<span class="u-like-count">{{
|
|
50
|
+
likesFormat(hasLikeCount)
|
|
51
|
+
}}</span></el-button
|
|
52
|
+
>
|
|
25
53
|
<el-button
|
|
26
54
|
class="u-admin"
|
|
27
55
|
v-if="canReply"
|
|
28
56
|
link
|
|
29
57
|
icon="ChatLineRound"
|
|
30
58
|
size="small"
|
|
31
|
-
@click="showReplyForReplyInput
|
|
59
|
+
@click="showReplyForReplyInput"
|
|
32
60
|
type="primary"
|
|
33
61
|
>回复</el-button
|
|
34
62
|
>
|
|
@@ -39,9 +67,20 @@
|
|
|
39
67
|
icon="Delete"
|
|
40
68
|
size="small"
|
|
41
69
|
type="danger"
|
|
42
|
-
@click="deleteComment
|
|
70
|
+
@click="deleteComment"
|
|
43
71
|
>删除</el-button
|
|
44
72
|
>
|
|
73
|
+
<el-button
|
|
74
|
+
class="u-admin"
|
|
75
|
+
type="text"
|
|
76
|
+
size="mini"
|
|
77
|
+
icon="Delete"
|
|
78
|
+
v-if="canHide"
|
|
79
|
+
@click="hideComment"
|
|
80
|
+
title="拉入黑洞后,仅评论者自己独自可见"
|
|
81
|
+
>
|
|
82
|
+
黑洞</el-button
|
|
83
|
+
>
|
|
45
84
|
<time class="u-date">
|
|
46
85
|
<i class="Clock"></i>
|
|
47
86
|
{{ dataFormat(date) }}
|
|
@@ -58,13 +97,16 @@ function fillZero(num) {
|
|
|
58
97
|
}
|
|
59
98
|
export default {
|
|
60
99
|
props: [
|
|
61
|
-
|
|
100
|
+
"commentId",
|
|
62
101
|
"content",
|
|
63
102
|
"attachments",
|
|
64
103
|
"date",
|
|
65
104
|
"hasReply",
|
|
66
105
|
"canDelete",
|
|
106
|
+
"canHide",
|
|
67
107
|
"canReply",
|
|
108
|
+
"isLike", // 是否已点赞
|
|
109
|
+
"likes", // 点赞数
|
|
68
110
|
"userHref",
|
|
69
111
|
"replyForUsername",
|
|
70
112
|
"replyForUserId",
|
|
@@ -72,6 +114,10 @@ export default {
|
|
|
72
114
|
data: function () {
|
|
73
115
|
return {
|
|
74
116
|
showInput: false,
|
|
117
|
+
currentUserHadLike: this.isLike,
|
|
118
|
+
hasLikeCount: this.likes,
|
|
119
|
+
|
|
120
|
+
renderContent: "",
|
|
75
121
|
};
|
|
76
122
|
},
|
|
77
123
|
computed: {
|
|
@@ -81,6 +127,14 @@ export default {
|
|
|
81
127
|
});
|
|
82
128
|
},
|
|
83
129
|
},
|
|
130
|
+
watch: {
|
|
131
|
+
content: {
|
|
132
|
+
handler: function (val) {
|
|
133
|
+
this.formatContent(val);
|
|
134
|
+
},
|
|
135
|
+
immediate: true,
|
|
136
|
+
},
|
|
137
|
+
},
|
|
84
138
|
methods: {
|
|
85
139
|
profileLink: function (uid) {
|
|
86
140
|
return authorLink(uid);
|
|
@@ -88,10 +142,22 @@ export default {
|
|
|
88
142
|
showAttachment: function (val) {
|
|
89
143
|
return resolveImagePath(val) + "?x-oss-process=style/comment_thumb";
|
|
90
144
|
},
|
|
91
|
-
formatContent
|
|
145
|
+
async formatContent(str) {
|
|
146
|
+
this.renderContent = await formatContent(str);
|
|
147
|
+
},
|
|
92
148
|
getPList(content) {
|
|
93
149
|
return content.split("\n");
|
|
94
150
|
},
|
|
151
|
+
doLike(setLike) {
|
|
152
|
+
if (setLike === this.currentUserHadLike) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
this.currentUserHadLike = setLike;
|
|
156
|
+
this.hasLikeCount = setLike
|
|
157
|
+
? this.hasLikeCount + 1
|
|
158
|
+
: this.hasLikeCount - 1;
|
|
159
|
+
this.$emit("setLikeComment", setLike);
|
|
160
|
+
},
|
|
95
161
|
deleteComment() {
|
|
96
162
|
this.$confirm("确定删除该评论吗?", "提示", {
|
|
97
163
|
confirmButtonText: "确定",
|
|
@@ -103,6 +169,20 @@ export default {
|
|
|
103
169
|
})
|
|
104
170
|
.catch(() => {});
|
|
105
171
|
},
|
|
172
|
+
hideComment() {
|
|
173
|
+
this.$confirm("确定隐藏该评论吗?", "提示", {
|
|
174
|
+
confirmButtonText: "确定",
|
|
175
|
+
cancelButtonText: "取消",
|
|
176
|
+
type: "warning",
|
|
177
|
+
})
|
|
178
|
+
.then(() => {
|
|
179
|
+
this.$emit("hide", this.commentId);
|
|
180
|
+
})
|
|
181
|
+
.catch(() => {});
|
|
182
|
+
},
|
|
183
|
+
likesFormat(count) {
|
|
184
|
+
return count > 0 ? count : "";
|
|
185
|
+
},
|
|
106
186
|
dataFormat(str) {
|
|
107
187
|
let d = new Date(str);
|
|
108
188
|
return (
|
|
@@ -18,6 +18,12 @@
|
|
|
18
18
|
type="pop"
|
|
19
19
|
:max="6">
|
|
20
20
|
</Emotion>
|
|
21
|
+
<quickReply @reply="onQuickReply"></quickReply>
|
|
22
|
+
<div class="c-comment-secret">
|
|
23
|
+
<el-checkbox class="u-secret" v-model="is_secret" border size="small">悄悄话
|
|
24
|
+
<el-tooltip class="item" effect="dark" content="勾选悄悄话后仅作者和你可见,并且不可再变更状态" placement="top">
|
|
25
|
+
<el-icon><InfoFilled></InfoFilled></el-icon> </el-tooltip></el-checkbox>
|
|
26
|
+
</div>
|
|
21
27
|
</div>
|
|
22
28
|
<Uploader
|
|
23
29
|
class="u-uploader"
|
|
@@ -42,11 +48,13 @@
|
|
|
42
48
|
<script>
|
|
43
49
|
import Uploader from "./Upload.vue";
|
|
44
50
|
import Emotion from "@jx3box/jx3box-emotion/src/Emotion2.vue";
|
|
51
|
+
import QuickReply from "./QuickReply.vue";
|
|
45
52
|
|
|
46
53
|
export default {
|
|
47
54
|
components: {
|
|
48
55
|
Uploader,
|
|
49
|
-
Emotion
|
|
56
|
+
Emotion,
|
|
57
|
+
QuickReply
|
|
50
58
|
},
|
|
51
59
|
props: {
|
|
52
60
|
// 用于判定该评论组件是否在底部
|
|
@@ -65,7 +73,8 @@ export default {
|
|
|
65
73
|
newComment: {
|
|
66
74
|
content: ""
|
|
67
75
|
},
|
|
68
|
-
inputId: "textarea-top"
|
|
76
|
+
inputId: "textarea-top",
|
|
77
|
+
is_secret: false,
|
|
69
78
|
};
|
|
70
79
|
},
|
|
71
80
|
methods: {
|
|
@@ -77,6 +86,13 @@ export default {
|
|
|
77
86
|
this.attachmentUploadFinish([]);
|
|
78
87
|
}
|
|
79
88
|
},
|
|
89
|
+
onQuickReply(item) {
|
|
90
|
+
this.$emit("submit", {
|
|
91
|
+
content: item,
|
|
92
|
+
attachmentList: [],
|
|
93
|
+
is_template: 1,
|
|
94
|
+
});
|
|
95
|
+
},
|
|
80
96
|
// 文件上传完成后,进行数据提交
|
|
81
97
|
attachmentUploadFinish(data) {
|
|
82
98
|
this.$emit("submit", {
|
|
@@ -127,3 +143,17 @@ export default {
|
|
|
127
143
|
}
|
|
128
144
|
};
|
|
129
145
|
</script>
|
|
146
|
+
|
|
147
|
+
<style lang="less">
|
|
148
|
+
.c-comment-secret {
|
|
149
|
+
margin-left: 15px;
|
|
150
|
+
|
|
151
|
+
.u-secret {
|
|
152
|
+
display: flex;
|
|
153
|
+
align-items: center;
|
|
154
|
+
.el-checkbox__inner{
|
|
155
|
+
display:block;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
</style>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="c-comment-cmt">
|
|
3
|
-
<div>
|
|
3
|
+
<div class="c-comment-cmt__author">
|
|
4
4
|
<el-link
|
|
5
5
|
class="u-name"
|
|
6
6
|
type="primary"
|
|
@@ -9,26 +9,37 @@
|
|
|
9
9
|
>{{ username || "人字榜800线无名小侠" }}</el-link
|
|
10
10
|
>
|
|
11
11
|
<span class="u-mark u-top" v-if="item.is_top"
|
|
12
|
-
><
|
|
12
|
+
><el-icon><Download></Download></el-icon>置顶</span
|
|
13
13
|
>
|
|
14
14
|
<span class="u-mark u-star" v-if="item.is_star"
|
|
15
|
-
><
|
|
15
|
+
><el-icon><Star></Star></el-icon>精华</span
|
|
16
|
+
>
|
|
17
|
+
<span class="u-mark u-secret" v-if="item.is_secret"
|
|
18
|
+
><el-icon><Cherry></Cherry></el-icon>悄悄话</span
|
|
16
19
|
>
|
|
17
20
|
</div>
|
|
18
21
|
<CommentContent
|
|
19
|
-
|
|
22
|
+
:date="item.commentDate"
|
|
20
23
|
:content="item.content"
|
|
21
24
|
:comment-id="item.id"
|
|
22
25
|
:attachments="stringToArray(item.attachments)"
|
|
23
|
-
:can-delete="power.
|
|
24
|
-
:can-set-top="power.is_author && !item.is_top"
|
|
25
|
-
:can-cancel-top="power.is_author && item.is_top"
|
|
26
|
-
:can-set-star="!item.is_star && power.
|
|
27
|
-
:can-cancel-star="item.is_star &&
|
|
26
|
+
:can-delete="power.can_del || power.uid == item.userId"
|
|
27
|
+
:can-set-top="(power.is_author || power.is_editor) && !item.is_top"
|
|
28
|
+
:can-cancel-top="(power.is_author || power.is_editor) && item.is_top"
|
|
29
|
+
:can-set-star="!item.is_star && (power.is_author || power.is_editor)"
|
|
30
|
+
:can-cancel-star="item.is_star &&(power.is_author || power.is_editor)"
|
|
31
|
+
:can-add-white="!item.is_white && power.article_open_white == 1"
|
|
32
|
+
:can-remove-white="item.is_white && (power.is_author == 1 || power.is_editor == 1)"
|
|
33
|
+
:can-hide="(power.is_author == 1 || power.is_editor == 1)"
|
|
34
|
+
:is-like="item.is_likes == 1"
|
|
35
|
+
:likes="~~item.likes"
|
|
28
36
|
@addNewReply="addNewReply"
|
|
29
37
|
@deleteComment="deleteComment"
|
|
30
38
|
@setTopComment="setTopComment"
|
|
31
39
|
@setStarComment="setStarComment"
|
|
40
|
+
@setLikeComment="setLikeComment"
|
|
41
|
+
@setWhiteComment="setWhiteComment"
|
|
42
|
+
@hide="hideComment"
|
|
32
43
|
/>
|
|
33
44
|
<ReplyList
|
|
34
45
|
:data="replyList"
|
|
@@ -38,6 +49,8 @@
|
|
|
38
49
|
@deleteReply="deleteReply"
|
|
39
50
|
@goto="gotoReplyListIndex"
|
|
40
51
|
@resetReply="resetReply"
|
|
52
|
+
@setLikeComment="setLikeReply"
|
|
53
|
+
@hide="hideComment"
|
|
41
54
|
/>
|
|
42
55
|
</div>
|
|
43
56
|
</template>
|
|
@@ -86,12 +99,24 @@ export default {
|
|
|
86
99
|
deleteComment() {
|
|
87
100
|
this.$emit("deleteComment", this.item.id);
|
|
88
101
|
},
|
|
102
|
+
hideComment(){
|
|
103
|
+
this.$emit("hide", this.item.id);
|
|
104
|
+
},
|
|
89
105
|
setTopComment(setTop) {
|
|
90
106
|
this.$emit("setTopComment", this.item.id, setTop);
|
|
91
107
|
},
|
|
92
108
|
setStarComment(setStar) {
|
|
93
109
|
this.$emit("setStarComment", this.item.id, setStar);
|
|
94
110
|
},
|
|
111
|
+
setLikeComment(setLike) {
|
|
112
|
+
this.$emit("setLikeComment", this.item.id, setLike);
|
|
113
|
+
},
|
|
114
|
+
setLikeReply(id, setLike) {
|
|
115
|
+
this.$emit("setLikeComment", id, setLike);
|
|
116
|
+
},
|
|
117
|
+
setWhiteComment( white) {
|
|
118
|
+
this.$emit("setWhiteComment", this.item.id, white);
|
|
119
|
+
},
|
|
95
120
|
addNewReply(data) {
|
|
96
121
|
POST(`${this.baseApi}/comment/${this.item.id}/reply`, null, data)
|
|
97
122
|
.then(() => {
|
|
@@ -147,6 +172,9 @@ export default {
|
|
|
147
172
|
|
|
148
173
|
<style lang="less">
|
|
149
174
|
.c-comment-cmt {
|
|
175
|
+
.u-name{
|
|
176
|
+
margin-right: 6px;
|
|
177
|
+
}
|
|
150
178
|
.u-mark {
|
|
151
179
|
font-style: normal;
|
|
152
180
|
font-size: 12px;
|
|
@@ -168,5 +196,8 @@ export default {
|
|
|
168
196
|
margin-right: 2px;
|
|
169
197
|
}
|
|
170
198
|
}
|
|
199
|
+
.u-secret{
|
|
200
|
+
background-color:#ff99cc;
|
|
201
|
+
}
|
|
171
202
|
}
|
|
172
203
|
</style>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="c-jx3box-reply">
|
|
3
|
+
<el-popover
|
|
4
|
+
:visible-arrow="true"
|
|
5
|
+
placement="top"
|
|
6
|
+
ref="quickReply"
|
|
7
|
+
trigger="click"
|
|
8
|
+
popper-class="c-jx3box-reply-pop"
|
|
9
|
+
>
|
|
10
|
+
<div class="c-jx3box-reply-pop__content">
|
|
11
|
+
<el-icon class="u-close" @click="closePop"><Close></Close></el-icon>
|
|
12
|
+
<div class="u-title">快捷回复</div>
|
|
13
|
+
<div class="m-reply-list">
|
|
14
|
+
<div
|
|
15
|
+
class="m-reply-list__item"
|
|
16
|
+
v-for="(item, index) in replyTemplate"
|
|
17
|
+
:key="index"
|
|
18
|
+
@click="reply(item)"
|
|
19
|
+
>
|
|
20
|
+
{{ item }}
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
<template #reference>
|
|
25
|
+
<img
|
|
26
|
+
class="u-reference"
|
|
27
|
+
width="24"
|
|
28
|
+
height="24"
|
|
29
|
+
src="../../assets/img/comment.svg"
|
|
30
|
+
alt="comment"
|
|
31
|
+
/>
|
|
32
|
+
</template>
|
|
33
|
+
</el-popover>
|
|
34
|
+
</div>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<script>
|
|
38
|
+
import replyTemplate from "../../assets/data/reply_template.json";
|
|
39
|
+
export default {
|
|
40
|
+
name: "QuickReply",
|
|
41
|
+
data() {
|
|
42
|
+
return {
|
|
43
|
+
replyTemplate,
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
emits: ["reply"],
|
|
47
|
+
methods: {
|
|
48
|
+
// 关闭弹窗
|
|
49
|
+
closePop() {
|
|
50
|
+
if (this.$refs.quickReply) {
|
|
51
|
+
this.$refs.quickReply.doClose();
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
reply(item) {
|
|
55
|
+
this.$emit("reply", item);
|
|
56
|
+
this.closePop();
|
|
57
|
+
},
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
<style lang="less">
|
|
63
|
+
@import "../../assets/css/quick-reply.less";
|
|
64
|
+
</style>
|
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
<el-form-item>
|
|
19
19
|
<div class="c-comment-tools">
|
|
20
20
|
<el-icon class="u-upload-icon" @click="showUploader = !showUploader"><Picture /></el-icon>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
<Emotion
|
|
22
|
+
class="c-comment-emotion"
|
|
23
|
+
@selected="handleEmotionSelected"
|
|
24
|
+
type="pop"
|
|
25
|
+
:max="6">
|
|
26
|
+
</Emotion>
|
|
27
27
|
</div>
|
|
28
28
|
<Uploader
|
|
29
29
|
v-if="showUploader"
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
|
|
50
50
|
<script>
|
|
51
51
|
import Uploader from "./Upload.vue";
|
|
52
|
-
|
|
52
|
+
import Emotion from "@jx3box/jx3box-emotion/src/Emotion2.vue";
|
|
53
53
|
export default {
|
|
54
54
|
props: ["username", "userHref", "currentId"],
|
|
55
55
|
data: function () {
|
|
@@ -62,7 +62,7 @@ export default {
|
|
|
62
62
|
},
|
|
63
63
|
components: {
|
|
64
64
|
Uploader,
|
|
65
|
-
|
|
65
|
+
Emotion,
|
|
66
66
|
},
|
|
67
67
|
mounted() {
|
|
68
68
|
if (this.currentId) this.inputId = this.currentId;
|
|
@@ -10,17 +10,22 @@
|
|
|
10
10
|
/>
|
|
11
11
|
<!--评论主体内容-->
|
|
12
12
|
<CommentContentSimple
|
|
13
|
-
|
|
13
|
+
:comment-id="reply.id"
|
|
14
14
|
:date="reply.commentDate"
|
|
15
15
|
:content="reply.content"
|
|
16
16
|
:attachments="stringToArray(reply.attachments)"
|
|
17
|
-
:can-delete="power.
|
|
17
|
+
:can-delete="power.can_del || power.uid == reply.userId"
|
|
18
|
+
:can-hide="(power.is_author == 1 || power.is_editor == 1)"
|
|
18
19
|
:can-reply="power.uid != reply.userId"
|
|
19
20
|
:user-href="profileLink(reply.replyForUID)"
|
|
20
21
|
:reply-for-username="reply.replyForUsername"
|
|
21
22
|
:reply-for-user-id="reply.replyForUID"
|
|
23
|
+
:is-like="reply.is_likes == 1"
|
|
24
|
+
:likes="~~reply.likes"
|
|
22
25
|
@delete="deleteReply"
|
|
23
26
|
@showReplyInput="showReplyForReplyFrom = !showReplyForReplyFrom"
|
|
27
|
+
@setLikeComment="setLikeComment"
|
|
28
|
+
@hide="hideReply"
|
|
24
29
|
/>
|
|
25
30
|
<!--隐藏起来的回复评论的评论表单-->
|
|
26
31
|
<ReplyForReply
|
|
@@ -68,6 +73,12 @@ export default {
|
|
|
68
73
|
deleteReply(id) {
|
|
69
74
|
this.$emit("deleteReply", id);
|
|
70
75
|
},
|
|
76
|
+
hideReply(id) {
|
|
77
|
+
this.$emit("hide", id);
|
|
78
|
+
},
|
|
79
|
+
setLikeComment(setLike) {
|
|
80
|
+
this.$emit("setLikeComment", this.reply.id, setLike);
|
|
81
|
+
},
|
|
71
82
|
doReply(replyData) {
|
|
72
83
|
(replyData.replyForUID = this.reply.userId),
|
|
73
84
|
(replyData.replyForCommentId = this.reply.id),
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="c-comment-replylist" v-if="data.length">
|
|
3
3
|
<reply-item
|
|
4
|
-
|
|
4
|
+
class="c-comment-reply"
|
|
5
5
|
v-for="reply in data"
|
|
6
6
|
:key="reply.id"
|
|
7
7
|
:reply="reply"
|
|
8
8
|
:power="power"
|
|
9
9
|
@deleteReply="deleteReply"
|
|
10
10
|
@addReply="addReply"
|
|
11
|
+
@setLikeComment="setLikeComment"
|
|
12
|
+
@hide="hideReply"
|
|
11
13
|
/>
|
|
12
14
|
<!-- 分页 -->
|
|
13
15
|
<el-row v-if="data.length >= 3 || showPager">
|
|
@@ -42,7 +44,7 @@ export default {
|
|
|
42
44
|
showPager: false,
|
|
43
45
|
};
|
|
44
46
|
},
|
|
45
|
-
emits: ["goto", "resetReply", "deleteReply", "addNewReply"],
|
|
47
|
+
emits: ["goto", "resetReply", "deleteReply", "addNewReply", "setLikeComment", "hide"],
|
|
46
48
|
methods: {
|
|
47
49
|
showMore() {
|
|
48
50
|
this.showPager = true;
|
|
@@ -58,6 +60,12 @@ export default {
|
|
|
58
60
|
deleteReply(id) {
|
|
59
61
|
this.$emit("deleteReply", id);
|
|
60
62
|
},
|
|
63
|
+
hideReply(id) {
|
|
64
|
+
this.$emit("hide", id);
|
|
65
|
+
},
|
|
66
|
+
setLikeComment(id, isLike) {
|
|
67
|
+
this.$emit("setLikeComment", id, isLike);
|
|
68
|
+
},
|
|
61
69
|
addReply(data) {
|
|
62
70
|
this.$emit("addNewReply", data);
|
|
63
71
|
},
|
package/src/single/Comment.vue
CHANGED
|
@@ -2,16 +2,36 @@
|
|
|
2
2
|
<el-container class="c-comment" v-loading="loading">
|
|
3
3
|
<el-main>
|
|
4
4
|
<CommentInputForm @submit="userSubmitInputForm" />
|
|
5
|
-
<div class="c-comment-
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
<div class="c-comment-panel">
|
|
6
|
+
<div class="u-order">
|
|
7
|
+
<span class="u-label">排序模式:</span>
|
|
8
|
+
<el-radio-group
|
|
9
|
+
v-model="isDesc"
|
|
10
|
+
@change="changeOrder"
|
|
11
|
+
size="small"
|
|
12
|
+
>
|
|
13
|
+
<el-radio-button label="DESC">最后靠前</el-radio-button>
|
|
14
|
+
<el-radio-button label="ASC">最早靠前</el-radio-button>
|
|
15
|
+
</el-radio-group>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="u-op">
|
|
18
|
+
<el-switch
|
|
19
|
+
class="c-comment-panel-likes"
|
|
20
|
+
v-model="orderByLikes"
|
|
21
|
+
@change="changeOrderByLikes"
|
|
22
|
+
active-text="获赞靠前"
|
|
23
|
+
>
|
|
24
|
+
</el-switch>
|
|
25
|
+
<el-switch
|
|
26
|
+
class="c-comment-panel-likes"
|
|
27
|
+
v-model="openWhiteList"
|
|
28
|
+
@change="changeWhiteList"
|
|
29
|
+
v-if="commentPower.is_author || commentPower.is_editor"
|
|
30
|
+
active-text="开启过滤"
|
|
31
|
+
title="开启过滤后,仅设为显示的评论可被其他人所见"
|
|
32
|
+
>
|
|
33
|
+
</el-switch>
|
|
34
|
+
</div>
|
|
15
35
|
</div>
|
|
16
36
|
<template v-if="isNormal">
|
|
17
37
|
<div
|
|
@@ -37,6 +57,9 @@
|
|
|
37
57
|
@setStarComment="setStarComment"
|
|
38
58
|
:user-href="profileLink(item.userId)"
|
|
39
59
|
:username="item.displayName"
|
|
60
|
+
@setWhiteComment="setWhiteComment"
|
|
61
|
+
@setLikeComment="setLikeComment"
|
|
62
|
+
@hide="hideComment"
|
|
40
63
|
/>
|
|
41
64
|
</div>
|
|
42
65
|
|
|
@@ -106,6 +129,10 @@ export default {
|
|
|
106
129
|
this.reloadCommentList(this.pager.index);
|
|
107
130
|
setOrderMode(this.isDesc ? "DESC" : "ASC");
|
|
108
131
|
},
|
|
132
|
+
changeOrderByLikes() {
|
|
133
|
+
this.reloadCommentList(this.pager.index);
|
|
134
|
+
// setOrderMode(this.orderByLikes ? false : true);
|
|
135
|
+
},
|
|
109
136
|
setTopComment(id, setTop) {
|
|
110
137
|
const action = setTop ? "set" : "cancel";
|
|
111
138
|
PUT(`${this.baseAPI}/comment/${id}/top/${action}`)
|
|
@@ -114,6 +141,28 @@ export default {
|
|
|
114
141
|
})
|
|
115
142
|
.catch(() => {});
|
|
116
143
|
},
|
|
144
|
+
changeWhiteList() {
|
|
145
|
+
PUT(
|
|
146
|
+
`${this.baseAPI}/meta/white-list/${
|
|
147
|
+
this.openWhiteList ? "open" : "close"
|
|
148
|
+
}`
|
|
149
|
+
).then(()=>{
|
|
150
|
+
return this.reloadPower()
|
|
151
|
+
})
|
|
152
|
+
.then(() => {
|
|
153
|
+
this.commentPower.is_white = this.openWhiteList;
|
|
154
|
+
this.reloadCommentList(this.pager.index);
|
|
155
|
+
})
|
|
156
|
+
.catch(() => {});
|
|
157
|
+
},
|
|
158
|
+
setLikeComment(id, isLike) {
|
|
159
|
+
var action = isLike ? "like" : "unlike";
|
|
160
|
+
PUT(`${this.baseAPI}/comment/${id}/${action}`)
|
|
161
|
+
.then(() => {
|
|
162
|
+
// this.reloadCommentList(this.pager.index);
|
|
163
|
+
})
|
|
164
|
+
.catch(() => {});
|
|
165
|
+
},
|
|
117
166
|
setStarComment(id, setStar) {
|
|
118
167
|
const action = setStar ? "set" : "cancel";
|
|
119
168
|
PUT(`${this.baseAPI}/comment/${id}/star/${action}`)
|
|
@@ -122,6 +171,15 @@ export default {
|
|
|
122
171
|
})
|
|
123
172
|
.catch(() => {});
|
|
124
173
|
},
|
|
174
|
+
setWhiteComment(id, setWhite) {
|
|
175
|
+
// 设置某个评论为精选
|
|
176
|
+
var action = setWhite ? "add" : "remove";
|
|
177
|
+
PUT(`${this.baseAPI}/comment/${id}/white-list/${action}`)
|
|
178
|
+
.then(() => {
|
|
179
|
+
this.reloadCommentList(this.pager.index);
|
|
180
|
+
})
|
|
181
|
+
.catch(() => {});
|
|
182
|
+
},
|
|
125
183
|
deleteComment(id) {
|
|
126
184
|
DELETE(`${this.baseAPI}/comment/${id}`)
|
|
127
185
|
.then(() => {
|
|
@@ -136,6 +194,20 @@ export default {
|
|
|
136
194
|
})
|
|
137
195
|
.catch(() => {});
|
|
138
196
|
},
|
|
197
|
+
hideComment(id) {
|
|
198
|
+
PUT(`${this.baseAPI}/comment/${id}/hide`)
|
|
199
|
+
.then(() => {
|
|
200
|
+
this.$notify({
|
|
201
|
+
title: "",
|
|
202
|
+
message: "操作成功!",
|
|
203
|
+
type: "success",
|
|
204
|
+
duration: 3000,
|
|
205
|
+
position: "bottom-right",
|
|
206
|
+
});
|
|
207
|
+
this.reloadCommentList(this.pager.index);
|
|
208
|
+
})
|
|
209
|
+
.catch(() => {});
|
|
210
|
+
},
|
|
139
211
|
reloadCommentList(index) {
|
|
140
212
|
this.loading = true;
|
|
141
213
|
let orderQuery = {};
|
|
@@ -188,6 +260,14 @@ export default {
|
|
|
188
260
|
showAvatar: function (val) {
|
|
189
261
|
return showAvatar(val, 144);
|
|
190
262
|
},
|
|
263
|
+
reloadPower(){
|
|
264
|
+
GET(`${this.baseAPI}/i-am-author`)
|
|
265
|
+
.then((power) => {
|
|
266
|
+
this.commentPower = power;
|
|
267
|
+
this.openWhiteList = power.is_white;
|
|
268
|
+
})
|
|
269
|
+
.catch(() => {});
|
|
270
|
+
}
|
|
191
271
|
},
|
|
192
272
|
created() {
|
|
193
273
|
this.baseAPI = `/api/next2/comment/${this.category}/article/${this.id}`;
|
|
@@ -323,14 +403,15 @@ export default {
|
|
|
323
403
|
} */
|
|
324
404
|
}
|
|
325
405
|
}
|
|
326
|
-
.c-comment-
|
|
406
|
+
.c-comment-panel {
|
|
407
|
+
display: flex;
|
|
408
|
+
align-items: center;
|
|
409
|
+
justify-content: space-between;
|
|
327
410
|
background-color: #fafbfc;
|
|
328
411
|
padding: 8px 10px;
|
|
329
412
|
border-radius: 3px;
|
|
330
413
|
border: 1px solid #eee;
|
|
331
414
|
margin: 10px 0;
|
|
332
|
-
.flex;
|
|
333
|
-
align-items: center;
|
|
334
415
|
.u-label {
|
|
335
416
|
color: #666;
|
|
336
417
|
margin-right: 10px;
|
|
@@ -343,4 +424,19 @@ export default {
|
|
|
343
424
|
max-height: 168px;
|
|
344
425
|
overflow: auto;
|
|
345
426
|
}
|
|
427
|
+
.c-comment-panel-likes {
|
|
428
|
+
margin-left: 10px;
|
|
429
|
+
}
|
|
430
|
+
.c-comment-alert {
|
|
431
|
+
color: #e6a23c;
|
|
432
|
+
margin-left: 10px;
|
|
433
|
+
font-size: 12px;
|
|
434
|
+
}
|
|
435
|
+
@media screen and (max-width: 720px) {
|
|
436
|
+
.c-comment-panel {
|
|
437
|
+
.u-op{
|
|
438
|
+
display: none;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
346
442
|
</style>
|
package/utils/emotion.js
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
|
-
import JX3_EMOTION from
|
|
2
|
-
|
|
3
|
-
function
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import JX3_EMOTION from "@jx3box/jx3box-emotion";
|
|
2
|
+
function escapeHtml(str) {
|
|
3
|
+
return str.replace(/[<>"']/g, function (match) {
|
|
4
|
+
switch (match) {
|
|
5
|
+
case "<":
|
|
6
|
+
return "<";
|
|
7
|
+
case ">":
|
|
8
|
+
return ">";
|
|
9
|
+
case '"':
|
|
10
|
+
return """;
|
|
11
|
+
case "'":
|
|
12
|
+
return "'";
|
|
13
|
+
}
|
|
14
|
+
});
|
|
6
15
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
16
|
+
async function formatContent(val) {
|
|
17
|
+
const ins = new JX3_EMOTION(escapeHtml(val));
|
|
18
|
+
return await ins._renderHTML();
|
|
10
19
|
}
|
|
20
|
+
|
|
21
|
+
export { formatContent };
|