index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. <template>
  2. <view class="page_container">
  3. <z-paging
  4. ref="paging"
  5. :fixed="false"
  6. default-page-size="20"
  7. loading-full-fixed
  8. refresher-background="#05263c"
  9. v-model="momentsList"
  10. :show-loading-more-no-more-view="false"
  11. @query="queryList"
  12. @scroll="onScroll"
  13. >
  14. <moments-header
  15. :needTransparent="needTransparent"
  16. :baseUserInfo="baseUserInfo"
  17. showBack
  18. />
  19. <!-- <moments-item v-for="item in momentsList" :key="item.workMomentID" :moments="item" inSingle @startComent="startComent" /> -->
  20. <view v-for="group in groups">
  21. <view class="moments" v-for="(item, i) in group.objects">
  22. <view class="moments_day">
  23. <text v-if="i === 0">{{ group.date }}</text>
  24. </view>
  25. <view
  26. class="moments_content"
  27. v-if="item.content.metas.length > 0"
  28. @click="toDetails(item.workMomentID)"
  29. >
  30. <image :src="item.content.metas[0].thumb"></image>
  31. <view class="moments_content_text">
  32. <text class="main-text">{{ item.content.text }}</text>
  33. <text class="tip-text">共{{ item.content.metas.length }}张</text>
  34. </view>
  35. </view>
  36. <view
  37. class="moments_content"
  38. @click="toDetails(item.workMomentID)"
  39. v-else
  40. >
  41. <view class="moments_only_text">
  42. <text class="only-text">{{ item.content.text }}</text>
  43. </view>
  44. </view>
  45. </view>
  46. </view>
  47. <view slot="loading" class="loading_wrap">
  48. <u-loading-icon text="加载中"></u-loading-icon>
  49. </view>
  50. <comment-input
  51. slot="bottom"
  52. ref="commentInputRef"
  53. v-show="commenting"
  54. :loading="commentLoading"
  55. :commenting="commenting"
  56. :placeholder="placeholder"
  57. @completeInput="sendComment"
  58. @hiddenInput="commenting = false"
  59. />
  60. </z-paging>
  61. </view>
  62. </template>
  63. <script>
  64. import { v4 as uuidv4 } from "uuid";
  65. import dayjs from "dayjs";
  66. import CustomNavBar from "../../../components/CustomNavBar/index.vue";
  67. import { commentMoments, getUserMomentsSplit } from "../../../api/moments";
  68. import MomentsHeader from "../index/components/MomentsHeader.vue";
  69. import MomentsItem from "../index/components/MomentsItem.vue";
  70. import CommentInput from "../index/components/CommentInput.vue";
  71. import { PageEvents } from "../../../constant";
  72. export default {
  73. components: {
  74. MomentsHeader,
  75. MomentsItem,
  76. CustomNavBar,
  77. CommentInput,
  78. },
  79. data() {
  80. return {
  81. commenting: false,
  82. isFocus: false,
  83. needTransparent: true,
  84. momentsList: [],
  85. commentState: {
  86. workMomentID: "",
  87. comment: {},
  88. },
  89. commentLoading: false,
  90. baseUserInfo: {},
  91. };
  92. },
  93. computed: {
  94. placeholder() {
  95. if (this.commentState.comment.userID) {
  96. return `回复${this.commentState.comment.nickname}`;
  97. }
  98. return "评论";
  99. },
  100. groups() {
  101. const groupsMap = new Map();
  102. const currentDate = dayjs().format("YYYY-MM-DD");
  103. this.momentsList.forEach((obj) => {
  104. const objDate = dayjs.unix(obj.createTime / 1000);
  105. if (objDate.format("YYYY-MM-DD") === currentDate) {
  106. const todayKey = "今日";
  107. if (!groupsMap.has(todayKey)) {
  108. groupsMap.set(todayKey, []);
  109. }
  110. groupsMap.get(todayKey).push(obj);
  111. } else if (objDate.add(1, "day").format("YYYY-MM-DD") === currentDate) {
  112. const yesterdayKey = "昨日";
  113. if (!groupsMap.has(yesterdayKey)) {
  114. groupsMap.set(yesterdayKey, []);
  115. }
  116. groupsMap.get(yesterdayKey).push(obj);
  117. } else {
  118. const otherKey = objDate.format("MM-DD");
  119. if (!groupsMap.has(otherKey)) {
  120. groupsMap.set(otherKey, []);
  121. }
  122. groupsMap.get(otherKey).push(obj);
  123. }
  124. });
  125. return Array.from(groupsMap, ([date, objects]) => ({
  126. date,
  127. objects,
  128. }));
  129. },
  130. },
  131. onLoad(options) {
  132. this.baseUserInfo = JSON.parse(options.baseUserInfo);
  133. this.setPageListener();
  134. uni.addInterceptor("navigateTo", {
  135. success: () => {
  136. if (this.commenting) {
  137. this.commentState.workMomentID = "";
  138. this.commentState.comment = {};
  139. this.commenting = false;
  140. }
  141. },
  142. });
  143. this.$nextTick(() => this.$refs.commentInputRef.setKeyboardListener());
  144. },
  145. onUnload() {
  146. this.$refs.commentInputRef.disposeKeyboardListener();
  147. },
  148. methods: {
  149. toDetails(workMomentID) {
  150. uni.$u.route("/pages/moments/momentsDetails/index", {
  151. workMomentID,
  152. });
  153. },
  154. queryList(pageNo, pageSize) {
  155. console.log(pageNo, pageSize);
  156. getUserMomentsSplit(this.baseUserInfo.userID, pageNo)
  157. .then((res) => {
  158. console.log("getUserMomentsSplit", res);
  159. this.$refs.paging.complete(res.workMoments);
  160. })
  161. .catch((err) => uni.$u.toast("获取工作圈数据失败!"));
  162. },
  163. startComent(workMomentID, comment) {
  164. this.commentState.workMomentID = workMomentID;
  165. this.commentState.comment = comment || {};
  166. this.commenting = true;
  167. this.$nextTick(() => (this.isFocus = true));
  168. },
  169. sendComment(content) {
  170. this.commentLoading = true;
  171. commentMoments(
  172. this.commentState.workMomentID,
  173. content,
  174. this.commentState.comment.userID,
  175. )
  176. .then(() => {
  177. const newComment = {
  178. userID: this.$store.getters.storeCurrentUserID,
  179. nickname: this.$store.getters.storeSelfInfo.nickname,
  180. replyUserID: this.commentState.comment.userID,
  181. replyNickname: this.commentState.comment.nickname,
  182. commentID: uuidv4(),
  183. content,
  184. };
  185. // this.pushNewComment(newComment)
  186. uni.$emit(
  187. PageEvents.PushNewComment,
  188. newComment,
  189. this.commentState.workMomentID,
  190. );
  191. })
  192. .catch((err) => uni.$u.toast("评论失败!"))
  193. .finally(() => {
  194. this.commentLoading = false;
  195. this.commentState.workMomentID = "";
  196. this.commentState.comment = {};
  197. this.commenting = false;
  198. });
  199. },
  200. pushNewComment(newComment, workMomentID) {
  201. const idx = this.momentsList.findIndex(
  202. (moments) =>
  203. moments.workMomentID ===
  204. (workMomentID || this.commentState.workMomentID),
  205. );
  206. if (idx > -1) {
  207. const tmpObj = {
  208. ...this.momentsList[idx],
  209. };
  210. tmpObj.comments = [...tmpObj.comments, newComment];
  211. this.momentsList[idx] = {
  212. ...tmpObj,
  213. };
  214. console.log(this.momentsList[idx]);
  215. this.$refs.paging.updateCache();
  216. }
  217. },
  218. onScroll(e) {
  219. this.needTransparent = e.detail.scrollTop < 200;
  220. },
  221. deleteMomentsHandler(workMomentID, isDetails) {
  222. if (!isDetails) {
  223. return;
  224. }
  225. const tmpList = [...this.momentsList];
  226. const idx = tmpList.findIndex(
  227. (moments) => moments.workMomentID === workMomentID,
  228. );
  229. if (idx > -1) {
  230. tmpList.splice(idx, 1);
  231. this.momentsList = [...tmpList];
  232. this.$refs.paging.updateCache();
  233. }
  234. },
  235. deleteCommentHandler(workMomentID, commentID, isDetails) {
  236. if (!isDetails) {
  237. return;
  238. }
  239. const idx = this.momentsList.findIndex(
  240. (moments) => moments.workMomentID === workMomentID,
  241. );
  242. if (idx > -1) {
  243. const tmpObj = {
  244. ...this.momentsList[idx],
  245. };
  246. const commentIdx = tmpObj.comments.findIndex(
  247. (comment) => comment.commentID === commentID,
  248. );
  249. tmpObj.comments.splice(commentIdx, 1);
  250. this.momentsList[idx] = {
  251. ...tmpObj,
  252. };
  253. this.$refs.paging.updateCache();
  254. }
  255. },
  256. operateLikeHandler(workMomentID, isLiked, isDetails) {
  257. if (!isDetails) {
  258. return;
  259. }
  260. console.log(workMomentID, isLiked);
  261. const idx = this.momentsList.findIndex(
  262. (moments) => moments.workMomentID === workMomentID,
  263. );
  264. if (idx === -1) return;
  265. const tmpObj = {
  266. ...this.momentsList[idx],
  267. };
  268. if (isLiked) {
  269. const likedIdx = tmpObj.likeUsers.findIndex(
  270. (user) => user.userID === this.$store.getters.storeCurrentUserID,
  271. );
  272. if (likedIdx > -1) {
  273. tmpObj.likeUsers.splice(likedIdx, 1);
  274. }
  275. } else {
  276. tmpObj.likeUsers.push({
  277. userID: this.$store.getters.storeCurrentUserID,
  278. nickname: this.$store.getters.storeSelfInfo.nickname,
  279. });
  280. }
  281. this.momentsList[idx] = {
  282. ...tmpObj,
  283. };
  284. this.$refs.paging.updateCache();
  285. },
  286. refershHandler() {
  287. this.$refs.paging.reload();
  288. },
  289. setPageListener() {
  290. uni.$on(PageEvents.PushNewComment, this.pushNewComment);
  291. uni.$on(PageEvents.DeleteComment, this.deleteCommentHandler);
  292. uni.$on(PageEvents.DeleteMoments, this.deleteMomentsHandler);
  293. uni.$on(PageEvents.OperateLike, this.operateLikeHandler);
  294. uni.$on(PageEvents.RefreshMoments, this.refershHandler);
  295. },
  296. disposePageListener() {
  297. uni.$off(PageEvents.PushNewComment, this.pushNewComment);
  298. uni.$off(PageEvents.DeleteComment, this.deleteCommentHandler);
  299. uni.$off(PageEvents.DeleteMoments, this.deleteMomentsHandler);
  300. uni.$off(PageEvents.OperateLike, this.operateLikeHandler);
  301. uni.$off(PageEvents.RefreshMoments, this.refershHandler);
  302. },
  303. },
  304. onBackPress() {
  305. if (this.commenting) {
  306. this.commenting = false;
  307. return true;
  308. }
  309. return false;
  310. },
  311. };
  312. </script>
  313. <style lang="scss" scoped>
  314. .page_container {
  315. background-color: #f8f8f8;
  316. position: relative;
  317. // height: calc(100vh - 55px);
  318. .moments {
  319. @include centerBox();
  320. align-items: flex-start;
  321. margin-bottom: 24rpx;
  322. &_day {
  323. @include centerBox();
  324. justify-content: center;
  325. font-weight: 600;
  326. font-size: 30rpx;
  327. flex-shrink: 0;
  328. width: 140rpx;
  329. }
  330. &_content {
  331. @include btwBox();
  332. flex: 1;
  333. flex-direction: row;
  334. .moments_only_text {
  335. width: 100%;
  336. background: #e8eaef;
  337. padding: 24rpx;
  338. margin-right: 24rpx;
  339. .only-text {
  340. @include ellipsisWithLine(2);
  341. }
  342. }
  343. image {
  344. flex-shrink: 0;
  345. width: 160rpx;
  346. height: 160rpx;
  347. }
  348. &_text {
  349. height: 160rpx;
  350. display: flex;
  351. flex: 1;
  352. flex-direction: column;
  353. justify-content: space-between;
  354. align-items: flex-start;
  355. margin: 0 24rpx;
  356. .main-text {
  357. @include ellipsisWithLine(3);
  358. }
  359. .tip-text {
  360. color: #8e9ab0;
  361. font-size: 26rpx;
  362. }
  363. }
  364. }
  365. }
  366. .loading_wrap {
  367. @include centerBox();
  368. height: 100%;
  369. }
  370. }
  371. </style>