hookehuyr

fix 评论功能细节调整

...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
25 <van-row> 25 <van-row>
26 <van-col span="16"> 26 <van-col span="16">
27 <p v-if="type === 'comment'" style="padding: 1rem; padding-top: 0;">请写下你友善的留言:</p> 27 <p v-if="type === 'comment'" style="padding: 1rem; padding-top: 0;">请写下你友善的留言:</p>
28 - <p v-else style="padding: 1rem; padding-top: 0;">回复<span style="color: #0B3A72;">@是妮妮吖~:</span></p> 28 + <p v-else style="padding: 1rem; padding-top: 0;">回复<span style="color: #0B3A72;">@{{ replayUser }}:</span></p>
29 </van-col> 29 </van-col>
30 <van-col span="8"> 30 <van-col span="8">
31 <div class="button-primary-comment" @click="submitComment">发送</div> 31 <div class="button-primary-comment" @click="submitComment">发送</div>
...@@ -66,7 +66,7 @@ import { ref, reactive, onMounted } from 'vue' ...@@ -66,7 +66,7 @@ import { ref, reactive, onMounted } from 'vue'
66 66
67 <script> 67 <script>
68 export default { 68 export default {
69 - props: ['showPopup', 'type'], 69 + props: ['showPopup', 'type', 'replayUser'],
70 data () { 70 data () {
71 return { 71 return {
72 show: false, 72 show: false,
......
1 <template> 1 <template>
2 <van-popup v-model:show="show" :close-on-click-overlay="false" round position="bottom" :style="{ height: '70%' }"> 2 <van-popup v-model:show="show" :close-on-click-overlay="false" round position="bottom" :style="{ height: '70%' }">
3 - <div class="van-hairline--bottom"> 3 + <div style="position: relative;">
4 - <van-row> 4 + <div class="van-hairline--bottom" style="position: fixed; width: 100%; background-color: white; border-radius: 10px; z-index: 999;">
5 - <van-col span="4" @click="onReload"> 5 + <van-row>
6 - <div style="padding: 1rem; text-align: center;"> 6 + <van-col span="4" @click="onReload">
7 - <van-icon :name="icon_x" size="1.25rem" /> 7 + <div style="padding: 1rem; text-align: center;">
8 + <!-- <van-icon :name="icon_x" size="1.25rem" /> -->
9 + </div>
10 + </van-col>
11 + <van-col span="16" style="color: #222222; text-align: center; line-height: 3;">
12 + <span>{{ data.total }}条回复</span>
13 + </van-col>
14 + <van-col span="4" @click="closeBtn">
15 + <div style="padding: 1rem;">
16 + <van-icon :name="icon_y" size="1.25rem" />
17 + </div>
18 + </van-col>
19 + </van-row>
20 + </div>
21 + <div style="height: 4rem;"></div>
22 + <van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad" :immediate-check="false">
23 + <template v-for="(item, key) in replyList" :key="key">
24 + <div class="comment-wrapper">
25 + <van-row style="font-size: 0.9rem;">
26 + <van-col span="4">
27 + <van-image round width="3rem" height="3rem" :src="item.avatar" />
28 + </van-col>
29 + <van-col span="14">
30 + <p>{{ item.name }}</p>
31 + <p>{{ item.kg_name }}</p>
32 + </van-col>
33 + <van-col span="6" style="text-align: right;">
34 + <p @click="setComment(item, 'reply')" style="color: #333333;">回复</p>
35 + <p>{{ item.comment_time }}</p>
36 + </van-col>
37 + </van-row>
38 + <van-row>
39 + <van-col offset="4">
40 + <span style="color: #222222;">{{ item.note }}</span>
41 + </van-col>
42 + </van-row>
8 </div> 43 </div>
9 - </van-col> 44 + </template>
10 - <van-col span="16" style="color: #222222; text-align: center; line-height: 3;"> 45 + </van-list>
11 - <span>{{ data.total }}条回复</span>
12 - </van-col>
13 - <van-col span="4" @click="closeBtn">
14 - <div style="padding: 1rem;">
15 - <van-icon :name="icon_y" size="1.25rem" />
16 - </div>
17 - </van-col>
18 - </van-row>
19 </div> 46 </div>
20 - <van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad" :immediate-check="false"> 47 + <comment-box :showPopup="showCommentBoxPopup" :type="commentType" :replayUser="replayUser" @on-submit="submitCommentBox" @on-close="closeCommentBox"></comment-box>
21 - <template v-for="(item, key) in replyList" :key="key">
22 - <div class="comment-wrapper">
23 - <van-row style="font-size: 0.9rem;">
24 - <van-col span="4">
25 - <van-image round width="3rem" height="3rem" :src="item.avatar" />
26 - </van-col>
27 - <van-col span="14">
28 - <p>{{ item.name }}</p>
29 - <p>{{ item.kg_name }}</p>
30 - </van-col>
31 - <van-col span="6" style="text-align: right;">
32 - <p style="color: #333333;">回复</p>
33 - <p>{{ item.comment_time }}</p>
34 - </van-col>
35 - </van-row>
36 - <van-row>
37 - <van-col offset="4">
38 - <span style="color: #222222;">{{ item.note }}</span>
39 - </van-col>
40 - </van-row>
41 - </div>
42 - </template>
43 - </van-list>
44 - <comment-box :showPopup="showCommentBoxPopup" :type="commentType" @on-close="closeCommentBox"></comment-box>
45 </van-popup> 48 </van-popup>
46 49
47 50
...@@ -58,42 +61,138 @@ import _ from 'lodash' ...@@ -58,42 +61,138 @@ import _ from 'lodash'
58 import { Toast } from 'vant'; 61 import { Toast } from 'vant';
59 62
60 import { ref, reactive, onMounted } from 'vue' 63 import { ref, reactive, onMounted } from 'vue'
61 -// const props = defineProps({ 64 +// 获取是否实名认证
62 -// showPopup: Boolean 65 +import { idCard } from '@/composables/useValidIdCard.js'
63 -// }) 66 +const validIdCard = idCard();
67 +
68 +const props = defineProps({
69 + showPopup: Boolean,
70 + data: Object
71 +})
64 72
73 +/******** 留言框相关操作 START *******/
65 // 回复评论控件 74 // 回复评论控件
66 const showCommentBoxPopup = ref(false); 75 const showCommentBoxPopup = ref(false);
67 const commentType = ref('comment'); // 类型 comment 为评论/类型 reply 为回复 76 const commentType = ref('comment'); // 类型 comment 为评论/类型 reply 为回复
68 -const flag = true; // 后台接口判断是否上传过作品 77 +
69 -// 实际调试时,点击回复需要判断是否上传过作品 78 +/**
70 -const setComment = (v, type) => { // 回复/评论 79 + * 回复/评论 功能
71 - if (flag) { 80 + * @param {*} v 单行评论数据
81 + * @param {*} type 类型 comment 为评论/类型 reply 为回复
82 + */
83 +const commentId = ref('')
84 +const replayUser = ref('')
85 +const setComment = (v, type) => { //
86 + if (validIdCard.can_use) {
72 showCommentBoxPopup.value = true; 87 showCommentBoxPopup.value = true;
73 commentType.value = type; 88 commentType.value = type;
89 + replayUser.value = v.name;
90 + commentId.value = props.data.id;
74 } else { 91 } else {
75 showNotice.value = true; 92 showNotice.value = true;
76 } 93 }
77 } 94 }
78 -const closeCommentBox = (v) => { // 查看更多回复 95 +
96 +/**
97 + * 提交留言回调
98 + * @param {*} note 留言内容
99 + */
100 +const submitCommentBox = (note) => {
101 + let url = '';
102 + let data = {}
103 + // 判断是留言还是回复 动态调整接口名称
104 + if (commentType.value === 'comment') {
105 + url = 'add_comment';
106 + data = {
107 + prod_id: $route.query.prod_id,
108 + note
109 + }
110 + } else {
111 + url = 'add_reply';
112 + data = {
113 + comment_id: commentId.value,
114 + note
115 + }
116 + }
117 + axios.post(`/srv/?a=${url}`, data)
118 + .then(res => {
119 + if (res.data.code === 1) {
120 + showCommentBoxPopup.value = false;
121 + Toast.success('发布成功')
122 + onReload()
123 + } else {
124 + console.warn(res);
125 + Toast({
126 + icon: 'close',
127 + message: res.data.msg
128 + });
129 + }
130 + })
131 + .catch(err => {
132 + console.error(err);
133 + })
134 +}
135 +
136 +const closeCommentBox = (v) => { // 关闭留言框
79 showCommentBoxPopup.value = v; 137 showCommentBoxPopup.value = v;
80 } 138 }
139 +/******** 留言框相关操作 START *******/
81 140
82 onMounted(() => { 141 onMounted(() => {
83 }) 142 })
143 +
144 +const show = ref(false);
145 +const replyList = ref([])
146 +const loading = ref(false)
147 +const finished = ref(false)
148 +const limit = ref(10)
149 +const offset = ref(0)
150 +
151 +const onLoad = () => {
152 + // 异步更新数据
153 + axios.get('/srv/?a=reply_list', {
154 + params: {
155 + comment_id: props.data.id,
156 + limit: limit.value,
157 + offset: offset.value
158 + }
159 + })
160 + .then(res => {
161 + if (res.data.code === 1) {
162 + replyList.value = _.concat(replyList.value, res.data.data.replylist);
163 + offset.value = replyList.value.length;
164 + loading.value = false;
165 + // 数据全部加载完成
166 + if (!res.data.data.replylist.length) {
167 + // 加载状态结束
168 + finished.value = true;
169 + }
170 + } else {
171 + console.warn(res);
172 + Toast({
173 + icon: 'close',
174 + message: res.data.msg
175 + });
176 + }
177 + })
178 + .catch(err => {
179 + console.error(err);
180 + })
181 +}
182 +const onReload = () => {
183 + replyList.value = [];
184 + offset.value = 0;
185 + onLoad();
186 +}
187 +const onClose = () => {
188 + show.value = false;
189 +}
84 </script> 190 </script>
85 191
86 <script> 192 <script>
87 export default { 193 export default {
88 - props: ['showPopup', 'data'],
89 data() { 194 data() {
90 return { 195 return {
91 - show: false,
92 - replyList: [],
93 - loading: false,
94 - finished: false,
95 - limit: 10,
96 - offset: 0,
97 } 196 }
98 }, 197 },
99 mounted() { 198 mounted() {
...@@ -107,45 +206,6 @@ export default { ...@@ -107,45 +206,6 @@ export default {
107 } 206 }
108 }, 207 },
109 methods: { 208 methods: {
110 - onLoad () {
111 - // 异步更新数据
112 - axios.get('/srv/?a=reply_list', {
113 - params: {
114 - comment_id: this.data.id,
115 - limit: this.limit,
116 - offset: this.offset
117 - }
118 - })
119 - .then(res => {
120 - if (res.data.code === 1) {
121 - this.replyList = _.concat(this.replyList, res.data.data.replylist);
122 - this.offset = this.replyList.length;
123 - this.loading = false;
124 - // 数据全部加载完成
125 - if (!res.data.data.replylist.length) {
126 - // 加载状态结束
127 - this.finished = true;
128 - }
129 - } else {
130 - console.warn(res);
131 - Toast({
132 - icon: 'close',
133 - message: res.data.msg
134 - });
135 - }
136 - })
137 - .catch(err => {
138 - console.error(err);
139 - })
140 - },
141 - onReload () {
142 - this.replyList = [];
143 - this.offset = 0;
144 - this.onLoad();
145 - },
146 - onClose() {
147 - this.show = false;
148 - },
149 closeBtn() { 209 closeBtn() {
150 this.$emit('on-close', false) 210 this.$emit('on-close', false)
151 this.show = false; 211 this.show = false;
......
...@@ -2,12 +2,15 @@ import { createApp } from 'vue'; ...@@ -2,12 +2,15 @@ import { createApp } from 'vue';
2 import { Button, Image as VanImage, Col, Row, Icon, Form, Field, CellGroup, ConfigProvider, Toast, Uploader, Empty, Tab, Tabs, Overlay, NumberKeyboard, Lazyload, List, PullRefresh, Popup, Picker, Sticky, Stepper, Tag, Swipe, SwipeItem, Dialog } from 'vant'; 2 import { Button, Image as VanImage, Col, Row, Icon, Form, Field, CellGroup, ConfigProvider, Toast, Uploader, Empty, Tab, Tabs, Overlay, NumberKeyboard, Lazyload, List, PullRefresh, Popup, Picker, Sticky, Stepper, Tag, Swipe, SwipeItem, Dialog } from 'vant';
3 import router from './router'; 3 import router from './router';
4 import App from './App.vue'; 4 import App from './App.vue';
5 -import axios from './utils/axios'; 5 +// import axios from './utils/axios';
6 +import axios from '@/utils/axios';
6 import { createPinia } from 'pinia'; 7 import { createPinia } from 'pinia';
7 8
8 const pinia = createPinia(); 9 const pinia = createPinia();
9 const app = createApp(App); 10 const app = createApp(App);
10 11
12 +app.config.globalProperties.$http = axios; // 关键语句
13 +
11 app.use(pinia); 14 app.use(pinia);
12 app.use(router); 15 app.use(router);
13 app.use(Button); 16 app.use(Button);
...@@ -39,6 +42,4 @@ app.use(Dialog); ...@@ -39,6 +42,4 @@ app.use(Dialog);
39 42
40 app.use(ConfigProvider); 43 app.use(ConfigProvider);
41 44
42 -app.config.globalProperties.$http = axios; // 关键语句
43 -
44 app.mount('#app'); 45 app.mount('#app');
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
28 <p v-if="reply.reply_to"><span>{{ reply.name }}</span>&nbsp;回复&nbsp;<span>@{{ reply.reply_to }}:</span><span class="content">{{ reply.note }}</span></p> 28 <p v-if="reply.reply_to"><span>{{ reply.name }}</span>&nbsp;回复&nbsp;<span>@{{ reply.reply_to }}:</span><span class="content">{{ reply.note }}</span></p>
29 <p v-else><span>{{ reply.name }}:</span><span class="content">{{ reply.note }}</span></p> 29 <p v-else><span>{{ reply.name }}:</span><span class="content">{{ reply.note }}</span></p>
30 </template> 30 </template>
31 - <p v-if="item.total !== reply_limit" @click="getMore(item)">共{{ item.total }}条回复 ></p> 31 + <p v-if="item.total >= reply_limit" @click="getReplyList(item)">共{{ item.total }}条回复 ></p>
32 </div> 32 </div>
33 </van-col> 33 </van-col>
34 </van-row> 34 </van-row>
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
41 </div> 41 </div>
42 </div> 42 </div>
43 <comment-list :showPopup="showCommentListPopup" :data="commentData" @on-close="closeCommentList"></comment-list> 43 <comment-list :showPopup="showCommentListPopup" :data="commentData" @on-close="closeCommentList"></comment-list>
44 - <comment-box :showPopup="showCommentBoxPopup" :type="commentType" @on-submit="submitCommentBox" @on-close="closeCommentBox"></comment-box> 44 + <comment-box :showPopup="showCommentBoxPopup" :type="commentType" :replayUser="replayUser" @on-submit="submitCommentBox" @on-close="closeCommentBox"></comment-box>
45 45
46 <!-- 写评论时,如果没有上传作品提示弹框 --> 46 <!-- 写评论时,如果没有上传作品提示弹框 -->
47 <van-overlay :show="showNotice" z-index="1000"> 47 <van-overlay :show="showNotice" z-index="1000">
...@@ -90,13 +90,12 @@ const $route = useRoute(); ...@@ -90,13 +90,12 @@ const $route = useRoute();
90 const $router = useRouter(); 90 const $router = useRouter();
91 91
92 92
93 -// 查询留言接口数据 93 +/******** 留言列表相关操作 START *******/
94 const loading = ref(false); 94 const loading = ref(false);
95 const finished = ref(false); 95 const finished = ref(false);
96 const limit = ref(5) 96 const limit = ref(5)
97 const offset = ref(0) 97 const offset = ref(0)
98 const reply_limit = ref(3) 98 const reply_limit = ref(3)
99 -
100 const commentList = ref([]) 99 const commentList = ref([])
101 100
102 const onLoad = () => { 101 const onLoad = () => {
...@@ -133,8 +132,6 @@ const onLoad = () => { ...@@ -133,8 +132,6 @@ const onLoad = () => {
133 }; 132 };
134 133
135 const onReload = () => { 134 const onReload = () => {
136 - // TODO: 初始化列表数据,会使得列表滚到最上面
137 - // 处理方法只能是插入相应的一条数据,这样就需要后台新增完成后,返回完整数据
138 commentList.value = []; 135 commentList.value = [];
139 offset.value = 0; 136 offset.value = 0;
140 onLoad(); 137 onLoad();
...@@ -160,21 +157,8 @@ const onReload = () => { ...@@ -160,21 +157,8 @@ const onReload = () => {
160 console.error(err); 157 console.error(err);
161 }) 158 })
162 } 159 }
160 +/******** 留言框列表相关操作 END *******/
163 161
164 -// 回复消息列表模块
165 -const showCommentListPopup = ref(false);
166 -const commentData = ref('')
167 -// 查看更多回复
168 -const getMore = (v) => {
169 - showCommentListPopup.value = true;
170 - commentData.value = v;
171 -}
172 -const closeCommentList = (v) => { // 查看更多回复
173 - showCommentListPopup.value = v;
174 -}
175 -// 回复评论控件
176 -const showCommentBoxPopup = ref(false);
177 -const commentType = ref('comment'); // 类型 comment 为评论/类型 reply 为回复
178 const showNotice = ref(false) 162 const showNotice = ref(false)
179 const closeNotice = () => { // 关闭提示框回调 163 const closeNotice = () => { // 关闭提示框回调
180 showNotice.value = false; 164 showNotice.value = false;
...@@ -183,16 +167,25 @@ const closeNotice = () => { // 关闭提示框回调 ...@@ -183,16 +167,25 @@ const closeNotice = () => { // 关闭提示框回调
183 }); 167 });
184 } 168 }
185 169
170 +
171 +/******** 留言框相关操作 START *******/
172 +// 回复评论控件
173 +const showCommentBoxPopup = ref(false);
174 +const commentType = ref('comment'); // 类型 comment 为评论/类型 reply 为回复
175 +
186 /** 176 /**
187 * 回复/评论 功能 177 * 回复/评论 功能
188 * @param {*} v 单行评论数据 178 * @param {*} v 单行评论数据
189 * @param {*} type 类型 comment 为评论/类型 reply 为回复 179 * @param {*} type 类型 comment 为评论/类型 reply 为回复
190 */ 180 */
191 const commentId = ref('') 181 const commentId = ref('')
182 +const replayUser = ref('')
183 +// TODO: 本人的评论还是应该把回复按钮屏蔽掉,后台要给个字段判断一下,comment_list/reply_list两个接口都要调整
192 const setComment = (v, type) => { // 184 const setComment = (v, type) => { //
193 if (validIdCard.can_use) { 185 if (validIdCard.can_use) {
194 showCommentBoxPopup.value = true; 186 showCommentBoxPopup.value = true;
195 commentType.value = type; 187 commentType.value = type;
188 + replayUser.value = v.name;
196 commentId.value = v.id; 189 commentId.value = v.id;
197 } else { 190 } else {
198 showNotice.value = true; 191 showNotice.value = true;
...@@ -226,7 +219,33 @@ const submitCommentBox = (note) => { ...@@ -226,7 +219,33 @@ const submitCommentBox = (note) => {
226 showCommentBoxPopup.value = false; 219 showCommentBoxPopup.value = false;
227 Toast.success('发布成功') 220 Toast.success('发布成功')
228 // 刷新列表 221 // 刷新列表
229 - // onReload(); 222 + if (commentType.value === 'comment') {
223 + // 留言可以刷新列表
224 + onReload();
225 + } else {
226 + // TODO: 初始化列表数据,会使得列表滚到最上面
227 + // 处理方法只能是插入相应的一条数据,这样就需要后台新增完成后,返回完整数据
228 + // 后端需要返回一个完整结构,我临时写进去
229 + let temp = {
230 + "id": 314178,
231 + "prod_id": 314058,
232 + "pid": 314171,
233 + "reply_to": "王申羽",
234 + "name": "王申羽",
235 + "avatar": "https://lanhu.oss-cn-beijing.aliyuncs.com/SketchPngf033a3cc00e4bb414ad696adbaf90a05f496c00e7210e889cd4ff3e4ea10ef24",
236 + "kg_name": "杨浦科技幼儿园",
237 + "note": "这是一条回复",
238 + "created_by": 314051,
239 + "comment_time": "5-4 07:03"
240 + }
241 +
242 + _.each(commentList.value, comment => {
243 + if (comment.id === commentId.value) {
244 + comment.reply_list.push(temp)
245 + comment.total = comment.total + 1
246 + }
247 + })
248 + }
230 // 不能刷新,只能插入 249 // 不能刷新,只能插入
231 } else { 250 } else {
232 console.warn(res); 251 console.warn(res);
...@@ -244,6 +263,21 @@ const submitCommentBox = (note) => { ...@@ -244,6 +263,21 @@ const submitCommentBox = (note) => {
244 const closeCommentBox = (v) => { // 关闭留言框 263 const closeCommentBox = (v) => { // 关闭留言框
245 showCommentBoxPopup.value = v; 264 showCommentBoxPopup.value = v;
246 } 265 }
266 +/******** 留言框相关操作 START *******/
267 +
268 +
269 +/******** 查看回复列表操作 START *******/
270 +const showCommentListPopup = ref(false);
271 +const commentData = ref({})
272 +// 查看更多回复
273 +const getReplyList = (v) => {
274 + showCommentListPopup.value = true;
275 + commentData.value = v;
276 +}
277 +const closeCommentList = (v) => { // 查看更多回复
278 + showCommentListPopup.value = v;
279 +}
280 +/******** 查看回复列表操作 END *******/
247 281
248 onMounted(() => { 282 onMounted(() => {
249 onLoad(); 283 onLoad();
......