list.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <template>
  2. <Theme>
  3. <view class="message-list-page">
  4. <!-- 导航栏 -->
  5. <Navbar title="系统消息" fixed border> </Navbar>
  6. <!-- Tab切换 -->
  7. <view class="tab-container" id="tabs">
  8. <view class="tab">
  9. <Tab
  10. :active="currentTab"
  11. keyName="text"
  12. :tabList="tabList"
  13. @confirm="tabClick"
  14. />
  15. </view>
  16. </view>
  17. <!-- 消息列表 -->
  18. <view class="message-list">
  19. <List
  20. url="/users/message"
  21. :topHeight="tabHeight"
  22. :defaultParams="defaultParams"
  23. ref="listRef"
  24. @datas="getList"
  25. >
  26. <template #item="{ item, index }">
  27. <view class="message-item" @click="goToDetail(item)">
  28. <!-- 消息内容 -->
  29. <view class="msg-content">
  30. <view class="msg-header">
  31. <text class="msg-title">{{ item.title }}</text>
  32. <text class="msg-time">{{
  33. useGlobal().$format(item.indate)
  34. }}</text>
  35. </view>
  36. <text class="msg-desc">{{ item.content }}</text>
  37. </view>
  38. <!-- 未读标识 -->
  39. <view class="reader-dot" v-if="item.reader"></view>
  40. <view class="unread-dot" v-if="!item.reader"></view>
  41. </view>
  42. </template>
  43. </List>
  44. </view>
  45. </view>
  46. </Theme>
  47. </template>
  48. <script setup>
  49. import { ref, reactive, computed, onMounted, nextTick } from "vue";
  50. import Navbar from "@/components/navbar";
  51. import Tab from "@/components/tabs";
  52. import List from "@/components/list";
  53. import { USERS_MESSAGE_READER, USERS_MESSAGE_UNREAD } from "@/api";
  54. import { t } from "@/locale";
  55. import { query, Toast, useGlobal } from "@/utils";
  56. import { onShow } from "@dcloudio/uni-app";
  57. const tabHeight = ref(0);
  58. const listRef = ref(null);
  59. const dataList = ref([]);
  60. const currentTab = ref(0);
  61. const tabList = ref([
  62. {
  63. text: "全部",
  64. channel: 0,
  65. key: "all",
  66. },
  67. {
  68. text: "未读",
  69. channel: 1,
  70. badge: 12,
  71. key: "unread",
  72. },
  73. ]);
  74. const defaultParams = reactive({
  75. status: tabList.value[currentTab.value].key,
  76. });
  77. // 消息列表数据
  78. const messages = ref([]);
  79. const getList = (list) => {
  80. dataList.value = list;
  81. };
  82. const tabClick = (item, index) => {
  83. defaultParams.status = item.key;
  84. if (currentTab.value == index) return;
  85. currentTab.value = index;
  86. nextTick(() => {
  87. listRef.value && listRef.value.handleRefresh();
  88. });
  89. };
  90. // 前往详情页
  91. const goToDetail = (item) => {
  92. // 标记为已读
  93. if (!item.reader) {
  94. USERS_MESSAGE_READER(item.id);
  95. }
  96. uni.navigateTo({
  97. url: `/pages/user/message/detail?id=${item.id}`,
  98. });
  99. };
  100. const getUnread = async () => {
  101. try {
  102. const res = await USERS_MESSAGE_UNREAD();
  103. tabList.value[1].badge = res.data.unread;
  104. } catch (error) {
  105. Toast(error.msg);
  106. }
  107. };
  108. onShow(() => {
  109. nextTick(() => {
  110. getUnread();
  111. listRef.value && listRef.value.getData();
  112. });
  113. });
  114. // 初始化
  115. onMounted(() => {
  116. nextTick(async () => {
  117. const res = await query("#tabs", this);
  118. tabHeight.value = res.height;
  119. });
  120. });
  121. </script>
  122. <style lang="less" scoped>
  123. @import url("@/style.less");
  124. .message-list-page {
  125. min-height: 100vh;
  126. }
  127. // Tab容器样式
  128. .tab-container {
  129. background-color: var(--light);
  130. padding: 0 48rpx;
  131. }
  132. // 消息列表样式
  133. .message-list {
  134. padding: 24rpx;
  135. width: 100%;
  136. .message-item {
  137. display: flex;
  138. align-items: center;
  139. padding: 24rpx;
  140. box-shadow: 0px 8rpx 20rpx 0px var(--bor-color1);
  141. margin-top: 16rpx;
  142. border-radius: 20rpx;
  143. transition: background-color 0.2s;
  144. &:last-child {
  145. border-bottom: none;
  146. }
  147. &:active {
  148. background-color: #f5f5f5;
  149. }
  150. &.unread {
  151. background-color: #f0f7ff;
  152. }
  153. .msg-content {
  154. flex: 1;
  155. overflow: hidden;
  156. .msg-header {
  157. display: flex;
  158. justify-content: space-between;
  159. margin-bottom: 8rpx;
  160. .msg-title {
  161. font-size: 32rpx;
  162. color: #333;
  163. font-weight: 500;
  164. max-width: 70%;
  165. white-space: nowrap;
  166. overflow: hidden;
  167. text-overflow: ellipsis;
  168. }
  169. .msg-time {
  170. font-size: 24rpx;
  171. color: #999;
  172. }
  173. }
  174. .msg-desc {
  175. font-size: 28rpx;
  176. color: #666;
  177. display: -webkit-box;
  178. -webkit-line-clamp: 1;
  179. -webkit-box-orient: vertical;
  180. overflow: hidden;
  181. }
  182. }
  183. .unread-dot {
  184. width: 16rpx;
  185. height: 16rpx;
  186. border-radius: 50%;
  187. background-color: #f53f3f;
  188. margin-left: 16rpx;
  189. }
  190. .reader-dot {
  191. width: 16rpx;
  192. height: 16rpx;
  193. margin-left: 16rpx;
  194. }
  195. }
  196. }
  197. </style>