当前位置:   article > 正文

uniapp实现一个评论区_uniapp 评论

uniapp 评论

目录

1.  评论区效果

2. 代码实现

3. 封装组件代码index.vue

4. 组件代码

5.组件的使用

6. 评论区数据格式


1.  评论区效果

还是话不多说,先上效果图

2. 代码实现

分父级(主评论)和子级(子评论)

自己回复的评论可以进行crud,  对于他人的评论仅仅只能评论

所以我们需要画出大致的布局,先上组件代码Index.vue代码,再上comment.vue

3. 封装组件代码index.vue
  1. <template>
  2. <view class="comment-eg">
  3. <view class="comment-space"></view>
  4. <hb-comment
  5. ref="hbComment"
  6. @share="share"
  7. @fold="fold"
  8. @add="add"
  9. @del="del"
  10. @like="like"
  11. @focusOn="focusOn"
  12. :deleteTip="'确认删除?'"
  13. :cmData="commentData"
  14. v-if="commentData"
  15. ></hb-comment>
  16. </view>
  17. </template>
  18. <script>
  19. import hbComment from "./hb-comment.vue";
  20. import { getCommentList } from "../../apis/metaUniverse";
  21. import {
  22. addMessageData,
  23. delMessageData,
  24. likeMessageData,
  25. } from "../../apis/index";
  26. export default {
  27. name: "comment-eg",
  28. data() {
  29. return {
  30. scriptCode: "",
  31. // nickName: '',
  32. userId: "",
  33. commentData: null,
  34. reqFlag: false, // 请求标志,防止重复操作,true表示请求中
  35. foldList: [], // 不需要折叠的id集合
  36. // userInfo: {},
  37. };
  38. },
  39. props: {
  40. articleId: {
  41. type: String,
  42. default: () => {
  43. return null;
  44. },
  45. },
  46. },
  47. watch: {
  48. articleId: {
  49. handler: function (newVal, oldVal) {
  50. if (newVal) {
  51. console.log("触发监听", newVal);
  52. this.scriptCode = newVal;
  53. this.foldList = [];
  54. this.getComment(newVal);
  55. }
  56. },
  57. immediate: true,
  58. },
  59. },
  60. created() {
  61. this.userId = uni.getStorageSync("userId") || "";
  62. },
  63. onShow() {
  64. },
  65. methods: {
  66. // 登录校验
  67. checkLogin() {
  68. // TODO 此处填写登录校验逻辑
  69. if (true) {
  70. return true;
  71. } else {
  72. uni.showModal({
  73. title: "提示",
  74. content: "请先登录",
  75. confirmText: "前往登录",
  76. success: function (res) {
  77. if (res.confirm) {
  78. uni.redirectTo({
  79. url: "/pages/login/login",
  80. });
  81. }
  82. },
  83. });
  84. return false;
  85. }
  86. },
  87. share() {
  88. console.log("点击转发");
  89. this.$emit("shareFriend");
  90. },
  91. // 输入框聚焦
  92. focusOn() {
  93. // this.checkLogin();
  94. },
  95. // 获取评论
  96. getComment(articleId) {
  97. // TODO 接入真实接口
  98. let sData = {
  99. scriptCode: this.scriptCode,
  100. userId: this.userId,
  101. };
  102. getCommentList(sData).then((res) => {
  103. let _this = this;
  104. res.data.forEach((item) => {
  105. item.isFold =
  106. !_this.foldList.includes(item.id) && item.children.length > 1
  107. ? true
  108. : false;
  109. });
  110. // console.log('评论结果', res.data)
  111. _this.commentData = {
  112. readNumer: res.data.length || 0,
  113. commentSize: res.data.length || 0,
  114. comment: res.data || [],
  115. };
  116. console.log("commentSize", _this.commentData.commentSize);
  117. });
  118. // 下边假装请求成功
  119. },
  120. fold(id) {
  121. this.foldList.push(id);
  122. console.log("需要展开的id合集", this.foldList);
  123. const foldIndex = this.commentData.comment.findIndex(
  124. (item) => item.id === id
  125. );
  126. console.log("展开评论222", foldIndex);
  127. this.$set(this.commentData.comment[foldIndex], "isFold", false);
  128. console.log("this.commentData", this.commentData.comment);
  129. },
  130. // 新增评论
  131. add(req) {
  132. req.userId = this.userId;
  133. req.scriptCode = this.scriptCode;
  134. console.log("新增评论接收到的结果", req);
  135. if (this.reqFlag) {
  136. return;
  137. }
  138. this.reqFlag = true;
  139. addMessageData(req).then((res) => {
  140. if (res.data) {
  141. uni.showToast({
  142. title: "评论成功",
  143. icon: "none",
  144. });
  145. this.reqFlag = false;
  146. this.$refs.hbComment.addComplete();
  147. this.getComment();
  148. } else {
  149. this.reqFlag = false;
  150. }
  151. });
  152. // TODO 接入真实接口
  153. },
  154. // 点赞评论
  155. like(comment) {
  156. if (this.reqFlag) {
  157. return;
  158. }
  159. this.reqFlag = true;
  160. console.log("点赞的参数", comment);
  161. let sData = {
  162. scriptCode: this.scriptCode,
  163. commentId: comment.commentId,
  164. status: comment.status,
  165. };
  166. let _this = this;
  167. likeMessageData(sData).then((res) => {
  168. if (res.data) {
  169. if (comment.status) {
  170. uni.showToast({
  171. title: "点赞成功",
  172. icon: "none",
  173. });
  174. }
  175. _this.reqFlag = false;
  176. _this.$refs.hbComment.likeComplete(comment.commentId);
  177. } else {
  178. _this.reqFlag = false;
  179. }
  180. });
  181. // TODO 接入真实接口
  182. },
  183. // 删除评论
  184. del(commentId) {
  185. console.log("获取到的id", commentId);
  186. if (this.reqFlag) {
  187. return;
  188. }
  189. this.reqFlag = true;
  190. let sData = {
  191. userId: this.userId,
  192. commentId: commentId,
  193. };
  194. let _this = this;
  195. delMessageData(sData).then((res) => {
  196. console.log("删除", res.data);
  197. if (res.data) {
  198. _this.reqFlag = false;
  199. _this.$refs.hbComment.deleteComplete(commentId);
  200. this.getComment();
  201. } else {
  202. _this.reqFlag = false;
  203. }
  204. });
  205. // TODO 接入真实接口
  206. },
  207. // 列表按照父子转换成树
  208. getTree(data) {
  209. let result = [];
  210. let map = {};
  211. data.forEach((item) => {
  212. map[item.id] = item;
  213. });
  214. data.forEach((item) => {
  215. let parent = map[item.parentId];
  216. if (parent) {
  217. (parent.children || (parent.children = [])).push(item);
  218. } else {
  219. result.push(item);
  220. }
  221. });
  222. console.log("父子树", result);
  223. return result;
  224. },
  225. },
  226. components: {
  227. hbComment,
  228. },
  229. };
  230. </script>
  231. <style>
  232. .comment-space {
  233. height: 12rpx;
  234. background: #f8f8f8;
  235. }
  236. </style>
4. 组件代码

comment.vue

  1. <template>
  2. <view class="hb-comment">
  3. <view class="comment-space"></view>
  4. <!-- 评论主体-start -->
  5. <view class="comment-list" v-if="commentData.comment.length != 0">
  6. <view class="comment-num">
  7. <view>评论</view>
  8. </view>
  9. <!-- 评论列表-start -->
  10. <view
  11. class="comment-box"
  12. v-for="(item, index) in commentData.comment"
  13. :key="item.id"
  14. >
  15. <view class="comment-box-item">
  16. <view>
  17. <image
  18. :src="item.headImg || emptyAvatar"
  19. mode="aspectFill"
  20. class="avatar-parent"
  21. ></image>
  22. </view>
  23. <view
  24. :class="[
  25. 'comment-main',
  26. { border_bottom: index + 1 !== commentData.commentSize },
  27. ]"
  28. >
  29. <!-- 父评论体-start -->
  30. <view class="comment-main-top">
  31. <view class="nick-name-box">
  32. <view class="nick-name">{{ item.nickName }}</view>
  33. </view>
  34. </view>
  35. <view class="comment-main-content">
  36. {{ item.content }}
  37. <view v-if="item.picUrl" @click="prviewImage(item.picUrl)">
  38. <image class="img" :src="item.picUrl" mode="widthFix"></image>
  39. </view>
  40. </view>
  41. <view class="comment-main-foot">
  42. <!-- <view class="foot-time">{{item.createTime}}</view> -->
  43. <view class="foot-time"
  44. >{{ getTimeInfo(item.commentTime)
  45. }}{{ `·${item.location}` }}</view
  46. >
  47. <view
  48. class="foot-btn foot-btn_common p-l40"
  49. @click="reply(item, 'reply')"
  50. >回复</view
  51. >
  52. <view
  53. class="foot-btn foot-btn_common p-l32"
  54. v-if="item.isMyComment"
  55. @click="confirmDelete(item.id)"
  56. >删除</view
  57. >
  58. <view class="zan-box">
  59. <span :class="item.isLike ? 'isLike' : 'notLike'">{{
  60. item.liked > 0 ? item.liked : ""
  61. }}</span>
  62. <!-- <span :class="item.isLike ? 'isLike' : 'notLike'">{{item.liked == 0 ? '抢首赞' : item.liked}}</span> -->
  63. <image
  64. @click.stop="like(item.id, 1)"
  65. v-if="!item.isLike"
  66. src="https://duoke-card.oss-cn-hangzhou.aliyuncs.com/A0gxSGwrgBvn890d208d4d79baec3a208abafd2096ee.png"
  67. />
  68. <image
  69. @click.stop="like(item.id, 0)"
  70. v-else
  71. src="https://duoke-card.oss-cn-hangzhou.aliyuncs.com/LQjAtVKGVRuT47750ea0ce1e2cb081672d92f52508c9.png"
  72. />
  73. </view>
  74. </view>
  75. <!-- 父评论体-end -->
  76. <!-- 子评论列表-start -->
  77. <view
  78. :class="[
  79. 'comment-sub-box',
  80. { 'comment-sub-box_empty': !item.children.length },
  81. ]"
  82. >
  83. <view v-for="(each, index) in item.children" :key="each.id">
  84. <view class="comment-sub-item" v-if="index < 1 && item.isFold">
  85. <view>
  86. <image
  87. :src="each.headImg || emptyAvatar"
  88. mode="aspectFill"
  89. class="avatar"
  90. >
  91. </image>
  92. </view>
  93. <view class="comment-main">
  94. <view class="sub-comment-main-top">
  95. <view class="nick-name">
  96. <view>{{ each.nickName }}</view>
  97. <view v-if="each.pnickName"
  98. ><span>回复</span>{{ each.pnickName }}</view
  99. >
  100. </view>
  101. </view>
  102. <view class="comment-main-content">
  103. {{ each.content }}
  104. <view
  105. v-if="each.picUrl"
  106. @click="prviewImage(each.picUrl)"
  107. >
  108. <image
  109. class="img"
  110. :src="each.picUrl"
  111. mode="widthFix"
  112. ></image>
  113. </view>
  114. </view>
  115. <view class="comment-main-foot">
  116. <view class="foot-time"
  117. >{{ getTimeInfo(each.commentTime)
  118. }}{{ `·${each.location}` }}</view
  119. >
  120. <view
  121. class="foot-btn foot-btn_common p-l40"
  122. @click="replyChild(each, item.id)"
  123. >
  124. 回复</view
  125. >
  126. <view
  127. class="foot-btn foot-btn_common p-l32"
  128. v-if="each.isMyComment"
  129. @click="confirmDelete(each.id)"
  130. >
  131. 删除
  132. </view>
  133. <view class="zan-box">
  134. <span :class="each.isLike ? 'isLike' : 'notLike'">{{
  135. each.liked > 0 ? each.liked : ""
  136. }}</span>
  137. <!-- <span :class="each.isLike ? 'isLike' : 'notLike'">{{each.liked == 0 ? '抢首赞' : each.liked}}</span> -->
  138. <image
  139. @click="like(each.id, 1)"
  140. v-if="!each.isLike"
  141. src="https://duoke-card.oss-cn-hangzhou.aliyuncs.com/A0gxSGwrgBvn890d208d4d79baec3a208abafd2096ee.png"
  142. />
  143. <image
  144. @click="like(each.id, 0)"
  145. v-else
  146. src="https://duoke-card.oss-cn-hangzhou.aliyuncs.com/LQjAtVKGVRuT47750ea0ce1e2cb081672d92f52508c9.png"
  147. />
  148. </view>
  149. </view>
  150. </view>
  151. </view>
  152. <view class="comment-sub-item" v-if="!item.isFold">
  153. <view>
  154. <image
  155. :src="each.headImg || emptyAvatar"
  156. mode="aspectFill"
  157. class="avatar"
  158. >
  159. </image>
  160. </view>
  161. <view class="comment-main">
  162. <view class="sub-comment-main-top">
  163. <view class="nick-name">
  164. <view>{{ each.nickName }}</view>
  165. <view v-if="each.pnickName"
  166. ><span>回复</span>{{ each.pnickName }}</view
  167. >
  168. </view>
  169. </view>
  170. <view class="comment-main-content">
  171. {{ each.content }}
  172. <view
  173. v-if="each.picUrl"
  174. @click="prviewImage(each.picUrl)"
  175. >
  176. <image
  177. class="img"
  178. :src="each.picUrl"
  179. mode="widthFix"
  180. ></image>
  181. </view>
  182. </view>
  183. <view class="comment-main-foot">
  184. <view class="foot-time"
  185. >{{ getTimeInfo(each.commentTime)
  186. }}{{ `·${each.location}` }}</view
  187. >
  188. <view
  189. class="foot-btn foot-btn_common p-l40"
  190. @click="replyChild(each, item.id)"
  191. >
  192. 回复</view
  193. >
  194. <view
  195. class="foot-btn foot-btn_common p-l32"
  196. v-if="each.isMyComment"
  197. @click="confirmDelete(each.id)"
  198. >
  199. 删除
  200. </view>
  201. <view class="zan-box">
  202. <span :class="each.isLike ? 'isLike' : 'notLike'">{{
  203. each.liked > 0 ? each.liked : ""
  204. }}</span>
  205. <!-- <span :class="each.isLike ? 'isLike' : 'notLike'">{{each.liked == 0 ? '抢首赞' : each.liked}}</span> -->
  206. <image
  207. @click="like(each.id, 1)"
  208. v-if="!each.isLike"
  209. src="https://duoke-card.oss-cn-hangzhou.aliyuncs.com/A0gxSGwrgBvn890d208d4d79baec3a208abafd2096ee.png"
  210. />
  211. <image
  212. @click="like(each.id, 0)"
  213. v-else
  214. src="https://duoke-card.oss-cn-hangzhou.aliyuncs.com/LQjAtVKGVRuT47750ea0ce1e2cb081672d92f52508c9.png"
  215. />
  216. </view>
  217. </view>
  218. </view>
  219. </view>
  220. </view>
  221. <view
  222. class="fold-more"
  223. v-if="item.isFold"
  224. @click="foldMsg(item.id)"
  225. >展开更多回复<u-icon size="14" name="arrow-down"></u-icon
  226. ></view>
  227. </view>
  228. <!-- 子评论列表-end -->
  229. </view>
  230. </view>
  231. </view>
  232. <!-- 评论列表-end -->
  233. </view>
  234. <!-- 评论主体-end -->
  235. <!-- 无评论-start -->
  236. <view class="comment-none" v-else>
  237. <view class="title">评论</view>
  238. <image
  239. mode="widthFix"
  240. src="https://dby-front-resource.oss-cn-hangzhou.aliyuncs.com/static/images/duke/meta-empty.png"
  241. class="top-bg"
  242. ></image>
  243. <view class="tips">快来抢沙发吧</view>
  244. <!-- 暂无评论,<span @click="commentInput" style="color: #007AFF;">抢沙发</span> -->
  245. </view>
  246. <!-- 无评论-end -->
  247. <!-- 发表评论-start -->
  248. <view class="comment-footer">
  249. <view class="comment-left" @click="reply('self')">说说你的想法</view>
  250. <view class="comment-right" @click="click_share">
  251. <image
  252. src="https://duoke-card.oss-cn-hangzhou.aliyuncs.com/EehiPALe7txe47f84c7f6483b3a3bb455aba32927dee.png"
  253. />
  254. <view class="label">转发</view>
  255. </view>
  256. </view>
  257. <!-- 评论弹框 -->
  258. <view class="comment-submit-box" v-if="submit" @click="closeInput">
  259. <view
  260. class="comment-add"
  261. @click.stop.prevent="stopPrevent"
  262. :style="'bottom:' + KeyboardHeight + 'px'"
  263. >
  264. <view class="comment-add_top">
  265. <textarea
  266. class="textarea"
  267. v-model="sendConf.content"
  268. :placeholder="placeholderTxt"
  269. :adjust-position="false"
  270. :show-confirm-bar="false"
  271. @blur="blur"
  272. @focus="focusOn"
  273. @input="sumfontnum"
  274. :focus="focus"
  275. maxlength="1000"
  276. auto-height
  277. ></textarea>
  278. <view class="pic-box">
  279. <view class="pic_box" v-if="sendConf.picUrl">
  280. <image
  281. class="del"
  282. v-if="upLoad"
  283. @click="delImg"
  284. src="https://duoke-card.oss-cn-hangzhou.aliyuncs.com/OvHnS9bQSAj5c959ff8678314f225057b163bfb36fe6.png"
  285. mode="aspectFill"
  286. ></image>
  287. <image
  288. class="pic"
  289. :src="sendConf.picUrl"
  290. mode="aspectFill"
  291. ></image>
  292. <view class="mask_progress" v-if="!upLoad">
  293. <view class="progress">
  294. <view class="label">{{ progress }}%</view>
  295. <view class="long" :style="'width:' + progress + '%'"></view
  296. ></view>
  297. </view>
  298. </view>
  299. </view>
  300. </view>
  301. <view
  302. class="comment-submit flex"
  303. :class="{ 'no-p': KeyboardHeight > 0 }"
  304. >
  305. <image
  306. @click="chooseImg"
  307. class="pic-icon"
  308. src="https://duoke-card.oss-cn-hangzhou.aliyuncs.com/nEJ0FD9ERL53978e81ece9b7f00201e14789d8f10ba2.png"
  309. mode="aspectFill"
  310. ></image>
  311. <view class="flex">
  312. <view class="num">{{ fontNum }}/1000</view>
  313. <view class="send" :class="{ nosend: permissSend }" @click="addMsg"
  314. >发送</view
  315. >
  316. </view>
  317. </view>
  318. </view>
  319. </view>
  320. <!-- 新增评论-end -->
  321. </view>
  322. </template>
  323. <script>
  324. import { getCommentImg } from "../../apis/metaUniverse";
  325. import ossUpload from "@/utils/ossUpload";
  326. export default {
  327. name: "hb-comment",
  328. props: {
  329. cmData: {
  330. type: Object,
  331. default: () => {
  332. return null;
  333. },
  334. },
  335. deleteTip: {
  336. type: String,
  337. default: () => {
  338. return "确认删除您的评论?";
  339. },
  340. },
  341. scriptCode: {
  342. type: String,
  343. default: "",
  344. },
  345. },
  346. watch: {
  347. cmData: {
  348. handler: function (newVal, oldVal) {
  349. console.log("监听到改变", newVal);
  350. this.init(newVal);
  351. this.$forceUpdate();
  352. },
  353. immediate: true,
  354. },
  355. },
  356. computed: {
  357. permissSend() {
  358. return (!this.sendConf.content.trim() && !this.sendConf.picUrl) ||
  359. !this.upLoad
  360. ? true
  361. : false;
  362. },
  363. fontNum() {
  364. return this.sendConf?.content?.length || 0;
  365. },
  366. placeholderTxt() {
  367. return this.sendConf.answerId === 0
  368. ? "说说你的想法"
  369. : `回复${this.sendConf.nickName}`;
  370. },
  371. },
  372. data() {
  373. return {
  374. emptyAvatar:
  375. "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAABF5JREFUWEfFl11oHFUUx//nbmKwxdJ9qFL7YPEhRJC2gljjF60WG0WsoNkWfSnZ7Jy7FVPF0AoKpmBFqyIG3Jk7G1iIQXHbBz+KbbGtRfBbMe2LseKjiVDoiqIhwZ0jV3fb3cnM7kQCuU+7M+ec/+9+nHPPEJZ50DLrY1EApVJp9fz8/BYRuZ2INgDYWJvAWRE5R0RnZmZmPh4ZGZlPOrFEAMVi8e4gCPYSUZ+IXGGFgiCYIaJpKyQi1yql1orIFgAXARxRSvm5XO67diBtAYwxRQCDAE4RUUkpdWxwcNCKLBiu665TSj0kIpqIbgTgMzO3gmgJYIz5CMB9AIaZ+bXGQMVi8RoRuZeI/lZKHc1ms3/U34+Pj6+cnZ3dC+AggGPMfH8cRCyAMUZqThlmPlwPUCgU0qlUyq7Kww1BrbjHzPsahYwx/QDK9hkzR2pFPjTGnAWwIexkjOkRkRIR3Rozo5Miskdr/VMIxE7mHDPXD+2l1wsA6nseBMHmfD7/dSjQOwB2tTlYC/bddd1blFJfARhj5lyjfxNA7bSfitpz3/d3iYgFaDuUUjeHM8AY8zSAV5VS9+RyudP1IE0Axpj3Aaxk5m1hFc/zPiWiO9uq/2dwiJn3h22NMScB/MnMOxYAjI6Orurq6rpgU0hrXYpw/hFAd0KAD5n5wbCt7/t7ROT1ubm5NUNDQ7/b95dWwHXd7Uqp452dnVcPDAxciACwDlclAbAFynGcdRGr2EtEnwdB0JfP5080ARhjDhLRbY7jbI0SMcZUAKxOAgDgN2ZOx8SxGfEiMz/bBOD7/lgQBCu01o/GOH4PYFNCgElmvinK1vf9X2xxchzHVtfLW2CMOQpgipmHYwBeBtBUaOJgRKSgtX48Js63AH5l5geaADzPe1cpddFxnHyM42YAXyZYAXt+epn557iVFJHzWuudYYDnlFJ9juPcESfi+35JRHa3gdjPzIfibIwxNtPe0Fq/EAZ4hIhcZl4T5+y67nql1CcA1kfZENFnrSZQ6ycqItKvtT4SBthIRJMdHR092WzW5nzk8H1/WEReiQHY4TjOB3G+nuf9qyEim7TW9r65fAjL5fKVlUrlPICXmPnNFquwWym1oFBZ+yAItubz+TMtAJ4gon3pdLo7k8nMNgHYP7ZeE5EWkbuYeaYx0NjY2HXValUDeApAV4zIJIADzPxe+H2hULg+lUp9U6sBl3qLprugXC6nKpXKF0R02nGcZ2wQ3/e3ichOEckQ0aoEWQDbsgF4a3p6eqLeH3qeN0FE3el0ujeTyVTrcaKuY1uIjIg8CaCfiLYnEW1hY4WPi8gEgMeY+e1G27iGxHYxtptZynGYmTPhgK1asqWEiBRfcAjDdMaYpYCIFW8LUMuM54nIsb3/YvbDXskiYtuzA6382n4X1CDWAnCSgNSFa98ETakcWbwWMytjzAoAPUEQ3JBKpXrs75r/VLVanVJK/VC7Uf9KGjfRCiQN9n/slh3gHz9i4jC+FVL5AAAAAElFTkSuQmCC",
  376. commentData: null,
  377. // placeholder: "说说你的想法",
  378. // pUser: null, // 标签-回复人
  379. showTag: false, // 标签展示与否
  380. focus: false, // 输入框自动聚焦
  381. submit: false, // 弹出评论
  382. KeyboardHeight: 0, // 键盘高度
  383. replayShow: false, // 展示弹框
  384. sendConf: {
  385. // id: 1,
  386. // nickName: '',
  387. // fileList: [],
  388. userId: null,
  389. content: "",
  390. picUrl: "",
  391. answerId: 0, // 评论id
  392. parentId: 0,
  393. location: "", // 评论的地址所在地
  394. },
  395. specialArea: ["澳门", "香港"],
  396. upLoad: true,
  397. progress: 0,
  398. };
  399. },
  400. onShow() {
  401. },
  402. mounted: function () {
  403. uni.onKeyboardHeightChange((res) => {
  404. this.KeyboardHeight = res.height;
  405. });
  406. },
  407. methods: {
  408. getImgUrl(){
  409. getCommentImg().then(res => {
  410. this.sendConf.picUrl = res.data;
  411. })
  412. },
  413. // 设置进度条
  414. setProgressData() {
  415. const timer = setInterval(() => {
  416. this.progress += 11;
  417. if (this.progress >= 99) {
  418. clearInterval(timer);
  419. }
  420. }, 5);
  421. },
  422. // 计算时间差
  423. getTimeInfo(time) {
  424. // commentTime
  425. let new_date = new Date(); //新建一个日期对象,默认现在的时间
  426. let old_date = new Date(time);
  427. let difftime = new_date - old_date;
  428. let days = parseInt(difftime / 1000 / 60 / 60 / 24); //24*60*60*1000
  429. let hours = parseInt(difftime / 1000 / 60 / 60); // 小时 60*60*1000
  430. let minutes = parseInt(difftime / 1000 / 60); // 分钟 -(day*24) 以60秒为一整份 取余 剩下秒数 秒数/60 就是分钟数
  431. if (hours >= 1 && hours < 24) {
  432. return `${hours}个小时前`;
  433. } else if (days >= 1) {
  434. if (days > 7) {
  435. return time.split(" ")[0];
  436. } else {
  437. return `${days}天前`;
  438. }
  439. } else {
  440. return minutes < 1 ? "刚刚" : `${minutes}分钟前`;
  441. }
  442. },
  443. sumfontnum(e) {
  444. let str = e.detail.value.trim();
  445. if (str.length >= 1000) {
  446. this.sendConf.content = e.detail.value.substring(0, 1000);
  447. } else {
  448. this.sendConf.content = e.detail.value;
  449. }
  450. },
  451. delImg() {
  452. this.sendConf.picUrl = "";
  453. this.progress = 0;
  454. this.upLoad = true;
  455. },
  456. // 选择图片
  457. chooseImg() {
  458. let _this = this;
  459. uni.getSetting({
  460. success(res) {
  461. if (res.authSetting["scope.writePhotosAlbum"]) {
  462. _this.chooseImage();
  463. } else {
  464. uni.authorize({
  465. scope: "scope.writePhotosAlbum",
  466. success() {
  467. _this.chooseImage();
  468. },
  469. fail(res) {
  470. uni.showToast({
  471. title: "请点击右上角“…”打开相册权限设置",
  472. icon: "none",
  473. duration: 2000,
  474. });
  475. },
  476. });
  477. }
  478. },
  479. });
  480. },
  481. chooseImage() {
  482. uni.chooseImage({
  483. count: 1,
  484. sizeType: ["compressed"],
  485. success: async (res) => {
  486. let imageSize = res.tempFiles[0].size;
  487. // 限制图片大小不超过2
  488. if (imageSize > 2097152) {
  489. uni.showToast({
  490. title: "图片超过2M!",
  491. icon: "none",
  492. });
  493. return;
  494. }
  495. this.upLoad = false;
  496. this.setProgressData();
  497. this.sendConf.picUrl = res.tempFiles[0].path;
  498. await ossUpload(res.tempFiles[0].path).then((imageResult) => {
  499. this.progress = 100;
  500. this.sendConf.picUrl = imageResult.url;
  501. this.upLoad = true;
  502. uni.showToast({
  503. title: "上传成功",
  504. icon: "none",
  505. });
  506. this.progress = 0;
  507. });
  508. // console.log('选择的图片', this.sendConf.picUrl);
  509. },
  510. fail: () => {
  511. this.upLoad = true;
  512. this.progress = 0;
  513. // uni.showToast({
  514. // title: "未",
  515. // icon: "none",
  516. // });
  517. },
  518. });
  519. },
  520. sendData() {
  521. // 调用接口
  522. },
  523. closePopup() {
  524. this.replayShow = false;
  525. this.resetSendData();
  526. },
  527. // 重置输入框的值
  528. resetSendData() {
  529. let keyNameList = ["content", "picUrl"];
  530. keyNameList.forEach((item) => {
  531. this.sendConf[item] = "";
  532. });
  533. this.sendConf.answerId = 0;
  534. this.sendConf.parentId = 0;
  535. this.progress = 0;
  536. this.upload = true;
  537. },
  538. click_share() {
  539. this.$emit("share");
  540. },
  541. foldMsg(id) {
  542. this.$emit("fold", id);
  543. },
  544. // 初始化评论
  545. init(cmData) {
  546. this.commentData = cmData;
  547. },
  548. // 没用的方法,但不要删
  549. stopPrevent() {},
  550. replyChild(e, parentId) {
  551. console.log("回复子评论");
  552. this.sendConf.nickName = e.nickName;
  553. this.sendConf.answerId = e.id;
  554. this.sendConf.parentId = parentId;
  555. this.showTag = true;
  556. this.commentInput();
  557. },
  558. // 预览图片
  559. prviewImage(imgUrl) {
  560. // console.log('预览图片', imgUrl);
  561. uni.previewImage({
  562. current: 0,
  563. urls: [imgUrl],
  564. });
  565. },
  566. // 回复评论
  567. reply(e, type) {
  568. this.getImgUrl();
  569. // let _this = this;
  570. switch (type) {
  571. case "self":
  572. // this.sendConf.nickName = e.nickName;
  573. this.sendConf.parentId = 0;
  574. break;
  575. case "reply":
  576. this.sendConf.nickName = e.nickName;
  577. this.sendConf.answerId = e.id;
  578. this.sendConf.parentId = e.id;
  579. break;
  580. }
  581. this.showTag = true;
  582. this.commentInput();
  583. },
  584. // 删除评论前确认
  585. confirmDelete(commentId) {
  586. let that = this;
  587. uni.showModal({
  588. title: "提示",
  589. content: "确认删除您的评论?",
  590. confirmText: "确认",
  591. success: function (res) {
  592. if (res.confirm) {
  593. that.$emit("del", commentId);
  594. }
  595. },
  596. });
  597. },
  598. // 新增评论
  599. addMsg() {
  600. if (this.permissSend) {
  601. return;
  602. }
  603. this.$emit("add", this.sendConf);
  604. },
  605. // 点赞评论
  606. like(commentId, status) {
  607. let sData = {
  608. commentId: commentId,
  609. status: status,
  610. };
  611. this.$emit("like", sData);
  612. },
  613. // 新增完成
  614. addComplete() {
  615. // this.sendConf.content = null;
  616. this.tagClose();
  617. this.closeInput();
  618. },
  619. // 点赞完成-本地修改点赞结果
  620. likeComplete(commentId) {
  621. for (var i in this.commentData.comment) {
  622. if (this.commentData.comment[i].id == commentId) {
  623. this.commentData.comment[i].isLike
  624. ? this.commentData.comment[i].liked--
  625. : this.commentData.comment[i].liked++;
  626. this.commentData.comment[i].isLike =
  627. !this.commentData.comment[i].isLike;
  628. return;
  629. }
  630. for (var j in this.commentData.comment[i].children) {
  631. if (this.commentData.comment[i].children[j].id == commentId) {
  632. this.commentData.comment[i].children[j].isLike
  633. ? this.commentData.comment[i].children[j].liked--
  634. : this.commentData.comment[i].children[j].liked++;
  635. this.commentData.comment[i].children[j].isLike =
  636. !this.commentData.comment[i].children[j].isLike;
  637. return;
  638. }
  639. }
  640. }
  641. },
  642. // 删除完成-本地删除评论
  643. deleteComplete(commentId) {
  644. for (let i in this.commentData.comment) {
  645. for (let j in this.commentData.comment[i].children) {
  646. if (this.commentData.comment[i].children[j].id == commentId) {
  647. this.commentData.comment[i].children.splice(Number(j), 1);
  648. return;
  649. }
  650. }
  651. if (this.commentData.comment[i].id == commentId) {
  652. this.commentData.comment.splice(Number(i), 1);
  653. return;
  654. }
  655. }
  656. },
  657. // 输入框失去焦点
  658. blur() {
  659. this.focus = false;
  660. },
  661. // 输入框聚焦
  662. focusOn() {
  663. this.$emit("focusOn");
  664. },
  665. // 标签关闭
  666. tagClose() {
  667. this.showTag = false;
  668. // this.pUser = null;
  669. // this.commentReq.pId = null;
  670. },
  671. // 输入评论
  672. commentInput() {
  673. // TODO 调起键盘方法
  674. this.submit = true;
  675. setTimeout(() => {
  676. this.focus = true;
  677. }, 50);
  678. },
  679. // 关闭输入评论
  680. closeInput() {
  681. console.log("关闭评论");
  682. this.focus = false;
  683. this.submit = false;
  684. this.resetSendData();
  685. },
  686. },
  687. };
  688. </script>
  689. <style lang="scss" scoped>
  690. .p-l32 {
  691. padding-left: 32rpx;
  692. }
  693. .p-l40 {
  694. padding-left: 40rpx;
  695. }
  696. .flex {
  697. display: flex;
  698. align-items: center;
  699. justify-content: space-between;
  700. }
  701. .fold-more {
  702. display: flex;
  703. font-size: 24rpx;
  704. font-family: PingFangSC-Medium, PingFang SC;
  705. font-weight: 500;
  706. color: #666666;
  707. line-height: 32rpx;
  708. padding-bottom: 32rpx;
  709. }
  710. .hb-comment {
  711. // padding: 10rpx;
  712. // margin-top: 12rpx;
  713. padding: 32rpx 0 32rpx 32rpx;
  714. background: #fff;
  715. padding-bottom: calc(
  716. 64rpx + constant(safe-area-inset-bottom)
  717. ); /** ios < 11.2 */
  718. padding-bottom: calc(64rpx + env(safe-area-inset-bottom)); /** ios >= 11.2 */
  719. }
  720. .top-read {
  721. font-size: 28rpx;
  722. padding-left: 10rpx;
  723. color: #999999;
  724. }
  725. .seg_line_box {
  726. display: flex;
  727. height: 5rpx;
  728. justify-content: space-between;
  729. margin: 5rpx 0;
  730. }
  731. .seg_line {
  732. width: 45%;
  733. border-bottom: 1rpx solid #e1e1e1;
  734. }
  735. .seg_dot {
  736. width: 8%;
  737. border-bottom: 5rpx dotted #dbdbdb;
  738. }
  739. .comment-num {
  740. display: flex;
  741. justify-content: space-between;
  742. align-items: center;
  743. // padding: 20rpx 0;
  744. height: 44rpx;
  745. font-size: 32rpx;
  746. font-family: PingFangSC-Medium, PingFang SC;
  747. font-weight: 500;
  748. color: #333333;
  749. line-height: 44rpx;
  750. }
  751. .comment-box {
  752. // padding: 10rpx 0;
  753. width: 714rpx;
  754. &:nth-last-child(1) {
  755. padding-bottom: 200rpx;
  756. }
  757. }
  758. .comment-box-item {
  759. display: flex;
  760. margin-top: 32rpx;
  761. }
  762. .comment-main {
  763. // padding-left: 20rpx;
  764. display: inline-block;
  765. white-space: pre-wrap;
  766. word-break: break-word;
  767. margin-left: 12rpx;
  768. width: 638rpx;
  769. }
  770. .border_bottom {
  771. position: relative;
  772. }
  773. .border_bottom::after {
  774. position: absolute;
  775. content: "";
  776. width: 100%;
  777. left: 0;
  778. bottom: 0;
  779. height: 2rpx;
  780. // padding: 0 28rpx;
  781. box-sizing: border-box;
  782. background-color: #e9e9e9;
  783. // background-color: red;
  784. -webkit-transform: scale(1, 0.5);
  785. transform: scale(1, 0.5);
  786. -webkit-transform-origin: center bottom;
  787. transform-origin: center bottom;
  788. }
  789. .comment-main-top {
  790. width: 600rpx;
  791. // padding-top: 6rpx;
  792. padding-top: 2rpx;
  793. display: flex;
  794. justify-content: space-between;
  795. }
  796. .sub-comment-main-top {
  797. // width: 510rpx;
  798. // padding-top: 6rpx;
  799. display: flex;
  800. justify-content: space-between;
  801. height: 34rpx;
  802. font-size: 24rpx;
  803. font-family: PingFangSC-Regular, PingFang SC;
  804. font-weight: 400;
  805. color: #999999;
  806. line-height: 34rpx;
  807. }
  808. .avatar {
  809. width: 36rpx;
  810. height: 36rpx;
  811. border-radius: 50%;
  812. }
  813. .avatar-parent {
  814. width: 68rpx;
  815. height: 68rpx;
  816. border-radius: 50%;
  817. }
  818. .nick-name-box {
  819. display: flex;
  820. align-items: center;
  821. }
  822. .comLogo {
  823. margin-right: 18rpx;
  824. font-size: 22rpx;
  825. border-radius: 10rpx;
  826. padding: 5rpx 15rpx;
  827. color: #ffffff;
  828. }
  829. .com1 {
  830. background-color: #d218b1;
  831. }
  832. .com2 {
  833. background-color: #f19c0b;
  834. }
  835. .com3 {
  836. background-color: #c8da85;
  837. }
  838. .com4 {
  839. background-color: #bfd0da;
  840. }
  841. .nick-name {
  842. // color: #2d8cf0;
  843. display: flex;
  844. height: 34rpx;
  845. font-size: 24rpx;
  846. font-family: PingFangSC-Regular, PingFang SC;
  847. font-weight: 400;
  848. color: #999999;
  849. line-height: 34rpx;
  850. span {
  851. margin: 0 12rpx;
  852. }
  853. }
  854. .isLike {
  855. font-size: 28rpx;
  856. padding-right: 10rpx;
  857. color: #476dff;
  858. }
  859. .notLike {
  860. font-size: 28rpx;
  861. padding-right: 10rpx;
  862. color: #999999;
  863. }
  864. .comment-main-content {
  865. // padding: 10rpx 10rpx 10rpx 0;
  866. display: inline-block;
  867. white-space: pre-wrap;
  868. word-break: break-word;
  869. padding: 12rpx 32rpx 12rpx 0rpx;
  870. font-size: 28rpx;
  871. font-family: PingFangSC-Regular, PingFang SC;
  872. font-weight: 400;
  873. color: #333333;
  874. line-height: 40rpx;
  875. .img {
  876. width: 160rpx;
  877. height: 160rpx;
  878. border-radius: 8rpx;
  879. margin-top: 12rpx;
  880. }
  881. }
  882. .comment-main-foot {
  883. display: flex;
  884. // font-size: 22rpx;
  885. font-size: 24rpx;
  886. font-family: PingFangSC-Regular, PingFang SC;
  887. font-weight: 400;
  888. color: #999999;
  889. line-height: 32rpx;
  890. padding-bottom: 24rpx;
  891. }
  892. .replayTag {
  893. color: #909399;
  894. margin-bottom: 5px;
  895. border: 1px solid #c8c9cc;
  896. background-color: #f4f4f5;
  897. border-radius: 3px;
  898. display: flex;
  899. justify-content: space-between;
  900. align-items: center;
  901. font-size: 16rpx;
  902. padding: 5px 10px;
  903. }
  904. .replyTagClose {
  905. font-size: 20px;
  906. line-height: 12px;
  907. padding: 0 0 2px 5px;
  908. }
  909. .foot-btn {
  910. // padding-left: 10rpx;
  911. color: #007aff;
  912. }
  913. .foot-btn_common {
  914. height: 32rpx;
  915. font-size: 24rpx;
  916. font-family: PingFangSC-Medium, PingFang SC;
  917. font-weight: 500;
  918. color: #666666;
  919. line-height: 32rpx;
  920. }
  921. .zan-box {
  922. display: flex;
  923. align-items: center;
  924. // margin-right: 32rpx;
  925. margin-left: auto;
  926. image {
  927. width: 28rpx;
  928. height: 28rpx;
  929. padding-right: 32rpx;
  930. }
  931. }
  932. .comment-sub-box {
  933. padding: 8rpx 0;
  934. }
  935. .comment-sub-box_empty {
  936. padding: 0;
  937. padding-bottom: 8rpx;
  938. }
  939. .comment-sub-item {
  940. display: flex;
  941. }
  942. .comment-none {
  943. // padding: 0 20rpx calc(100rpx + env(safe-area-inset-bottom));
  944. padding-bottom: calc(100rpx + env(safe-area-inset-bottom));
  945. width: 100%;
  946. text-align: center;
  947. color: #999999;
  948. .title {
  949. // padding: 20rpx 0;
  950. height: 44rpx;
  951. text-align: left;
  952. font-size: 32rpx;
  953. font-family: PingFangSC-Medium, PingFang SC;
  954. font-weight: 500;
  955. color: #333333;
  956. line-height: 44rpx;
  957. }
  958. .tips {
  959. font-size: 32rpx;
  960. font-family: PingFangSC-Regular, PingFang SC;
  961. font-weight: 400;
  962. color: #999999;
  963. line-height: 44rpx;
  964. }
  965. }
  966. .comment-footer {
  967. display: flex;
  968. justify-content: space-between;
  969. box-shadow: 0px -2rpx 0 0 rgba(0, 0, 0, 0.05);
  970. background: #fff;
  971. padding: 12rpx 32rpx 12rpx 24rpx;
  972. width: 750rpx;
  973. box-sizing: border-box;
  974. position: fixed;
  975. bottom: 0;
  976. left: 0;
  977. padding-bottom: calc(
  978. 12rpx + constant(safe-area-inset-bottom)
  979. ); /** ios < 11.2 */
  980. padding-bottom: calc(12rpx + env(safe-area-inset-bottom));
  981. .comment-left {
  982. box-sizing: border-box;
  983. // width: 622rpx;
  984. flex: 1;
  985. background: #f7f7f7;
  986. height: 80rpx;
  987. line-height: 80rpx;
  988. border-radius: 44rpx;
  989. padding-left: 40rpx;
  990. color: #9999;
  991. font-size: 28rpx;
  992. }
  993. .comment-right {
  994. padding-top: 6rpx;
  995. padding-left: 32rpx;
  996. image {
  997. width: 40rpx;
  998. height: 40rpx;
  999. }
  1000. .label {
  1001. font-size: 20rpx;
  1002. font-family: PingFangSC-Regular, PingFang SC;
  1003. font-weight: 400;
  1004. color: #666666;
  1005. line-height: 20rpx;
  1006. }
  1007. }
  1008. }
  1009. .comment-submit-box {
  1010. position: fixed;
  1011. display: flex;
  1012. align-items: flex-end;
  1013. z-index: 9900;
  1014. left: 0;
  1015. top: var(--window-top);
  1016. bottom: 0;
  1017. background-color: rgba($color: #000000, $alpha: 0.5);
  1018. width: 100%;
  1019. }
  1020. .comment-add {
  1021. position: fixed;
  1022. width: 100%;
  1023. box-sizing: border-box;
  1024. // padding: 5rpx;
  1025. // border: 1px solid #ddd;
  1026. // transition: .3s;
  1027. // -webkit-transition: .3s;
  1028. // padding: 24rpx 32rpx 32rpx 40rpx;
  1029. padding-top: 24rpx;
  1030. border-radius: 24rpx 24rpx 0 0;
  1031. background: #fff;
  1032. .comment-add_top {
  1033. overflow-y: scroll;
  1034. height: 300rpx;
  1035. }
  1036. textarea {
  1037. height: 184rpx;
  1038. width: 100%;
  1039. padding: 0 40rpx;
  1040. box-sizing: border-box;
  1041. // padding-right: 8rpx;
  1042. }
  1043. .pic_box {
  1044. position: relative;
  1045. width: 224rpx;
  1046. margin-top: 54rpx;
  1047. padding-left: 40rpx;
  1048. .pic {
  1049. width: 224rpx;
  1050. height: 224rpx;
  1051. border-radius: 8rpx;
  1052. }
  1053. .del {
  1054. z-index: 10;
  1055. width: 36rpx;
  1056. height: 36rpx;
  1057. border-radius: 50%;
  1058. position: absolute;
  1059. top: -18rpx;
  1060. right: -18rpx;
  1061. }
  1062. }
  1063. .mask_progress {
  1064. width: 224rpx;
  1065. height: 224rpx !important;
  1066. padding: 108rpx 21rpx;
  1067. border-radius: 8rpx;
  1068. box-sizing: border-box;
  1069. background: #333333;
  1070. position: absolute;
  1071. right: 0;
  1072. bottom: 0;
  1073. z-index: 2;
  1074. opacity: 0.8;
  1075. .progress {
  1076. width: 100%;
  1077. height: 100%;
  1078. border-radius: 1rpx;
  1079. .label {
  1080. margin-bottom: 2rpx;
  1081. text-align: center;
  1082. color: #fff;
  1083. font-size: 16rpx;
  1084. }
  1085. .long {
  1086. height: 3rpx;
  1087. background: white;
  1088. }
  1089. }
  1090. }
  1091. }
  1092. .btn-click {
  1093. color: #007aff;
  1094. font-size: 28rpx;
  1095. padding: 10rpx;
  1096. }
  1097. .cancel {
  1098. color: #606266;
  1099. }
  1100. // .textarea {
  1101. // height: 100px;
  1102. // padding: 16rpx;
  1103. // width: 100%;
  1104. // }
  1105. .comment-submit {
  1106. // padding: 5rpx 20rpx 0 20rpx;
  1107. border-bottom: 1rpx dashed #ddd;
  1108. // width: 100%;
  1109. display: flex;
  1110. justify-content: space-between;
  1111. align-items: center;
  1112. // padding: 16rpx 32rpx 16rpx 40rpx;
  1113. padding: 16rpx 32rpx calc(16rpx + env(safe-area-inset-bottom)) 40rpx;
  1114. box-shadow: 0 -2rpx 0rpx 0rpx rgba(0, 0, 0, 0.05);
  1115. .num {
  1116. height: 24rpx;
  1117. font-size: 24rpx;
  1118. font-family: PingFangSC-Regular, PingFang SC;
  1119. font-weight: 400;
  1120. color: #b3b3b3;
  1121. line-height: 24rpx;
  1122. }
  1123. .send {
  1124. width: 128rpx;
  1125. height: 64rpx;
  1126. background: #476dff;
  1127. border-radius: 32rpx;
  1128. margin-left: 24rpx;
  1129. text-align: center;
  1130. font-size: 32rpx;
  1131. font-family: PingFangSC-Medium, PingFang SC;
  1132. font-weight: 500;
  1133. color: #ffffff;
  1134. line-height: 64rpx;
  1135. }
  1136. .nosend {
  1137. opacity: 0.5;
  1138. }
  1139. .pic-icon {
  1140. width: 46rpx;
  1141. height: 42rpx;
  1142. margin: 5rpx 2rpx;
  1143. }
  1144. }
  1145. .no-p {
  1146. padding-bottom: 16rpx;
  1147. }
  1148. </style>
5.组件的使用
  1. <comment-eg v-if="!(!detailCollect.content && isNetWork)" :articleId="tempCode" @shareFriend="shareOthers"></comment-eg>
  2. // articleId是文章详情,通过id去调用接口获取评论区详情数据, shareothers是唤起微信的分享操作

无非就是写个评论区页面,将需要的参数通过props传入,将需要抛出的事件通过emit抛出

6. 评论区数据格式
  1. answerContent: null
  2. answerId: "0"
  3. answerPicUrl: null
  4. answerUserId: "0"
  5. children: [{id: "484", userId: "405298514273243136", answerUserId: "417213072755658752",…}]
  6. 0: {id: "484", userId: "405298514273243136", answerUserId: "417213072755658752",…}
  7. answerContent: ""
  8. answerId: "468"
  9. answerPicUrl: "https://images.dby.cn/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20230217095836%202023-10-20%2011_15_06.png"
  10. answerUserId: "417213072755658752"
  11. children: null
  12. commentTime: "2024-03-04 17:39:52"
  13. content: "评论组件"
  14. headImg: "https://duoke-card.oss-cn-hangzhou.aliyuncs.com/tmp_5ed263ea895cb9b6510b08375e350bdb0e2d7e915c739fc3.jpeg"
  15. id: "484"
  16. ipAddress: "124.90.42.134"
  17. isLike: false
  18. isMyComment: true
  19. liked: 0
  20. location: "浙江"
  21. nickName: "Mortimer"
  22. parentId: "468"
  23. pheadImg: "https://duoke-card.oss-cn-hangzhou.aliyuncs.com/tmp_7621a56009b34c01cc3c46feadcfbb8e.jpeg"
  24. picUrl: null
  25. pnickName: "你猜我猜你猜猜"
  26. scriptCode: "HJ1689172726976020481"
  27. status: false
  28. userId: "405298514273243136"
  29. commentTime: "2023-10-20 11:34:29"
  30. content: ""
  31. headImg: "https://duoke-card.oss-cn-hangzhou.aliyuncs.com/tmp_7621a56009b34c01cc3c46feadcfbb8e.jpeg"
  32. id: "468"
  33. ipAddress: "124.90.42.134"
  34. isLike: false
  35. isMyComment: false
  36. liked: 0
  37. location: "浙江"
  38. nickName: "你猜我猜你猜猜"
  39. parentId: "0"
  40. pheadImg: null
  41. picUrl: "https://images.dby.cn/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20230217095836%202023-10-20%2011_15_06.png"
  42. pnickName: null
  43. scriptCode: "HJ1689172726976020481"
  44. status: false
  45. userId: "417213072755658752"

有问题可以一起沟通哦~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/683514
推荐阅读
相关标签
  

闽ICP备14008679号