messageList.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <template>
  2. <view class="msg_list_content">
  3. <uni-collapse>
  4. <uni-collapse-item title-border="show" :border="true" :show-animation="anime" :open="open">
  5. <template v-slot:title>
  6. <uni-section :title="title" type="line" titleFontSize="1.5rem">
  7. <template v-slot:right>
  8. <uni-badge :text="unReadNum" style="margin-left: 5px;" v-if="unReadNum!==undefine&&unReadNum>0"></uni-badge>
  9. </template>
  10. </uni-section>
  11. </template>
  12. <View style="height: 67.8vh;">
  13. <z-paging :fixed="false" @query="queryData" :value="list" :default-page-size="pSize"
  14. :default-page-no="pageNo" ref="paging">
  15. <template #top>
  16. <view v-if="props.segments" class="segmented_control_container">
  17. <uni-segmented-control :current="current" :values="segmentKeys" @clickItem="onClickItem"
  18. styleType="text" activeColor="#409eff"></uni-segmented-control>
  19. </view>
  20. </template>
  21. <view @click="handleToDetail(message)" v-for="(message, index) in list" :key="index"
  22. :class="message.isread == 'Y' || message.if_read ? ' ' : 'message_container_unread'"
  23. class="message_container">
  24. <uni-card :is-full="true" padding="5px 10px">
  25. <template v-slot:title>
  26. <uni-row>
  27. <view class="message_top_container">
  28. <!-- <uni-col :span="24"> -->
  29. <text class="message_user">
  30. {{ message.name }}
  31. </text>
  32. <!-- </uni-col> -->
  33. </view>
  34. </uni-row>
  35. <uni-row>
  36. <view class="message_mid_container">
  37. <uni-col :xs="18" :sm="20">
  38. <view class="message_title hidden_over">
  39. {{ message.title }}
  40. </view>
  41. </uni-col>
  42. <uni-col :xs="6" :sm="4">
  43. <view class="message_time"
  44. v-for="(item, index) in message.sendtime.split(' ')" :key="index">
  45. {{ item }}
  46. </view>
  47. </uni-col>
  48. </view>
  49. </uni-row>
  50. </template>
  51. <view v-if="message.content" class="message_bottom_container">
  52. <text class="message_content hidden_over">
  53. {{ message.content }}
  54. </text>
  55. </view>
  56. </uni-card>
  57. </view>
  58. </z-paging>
  59. </View>
  60. </uni-collapse-item>
  61. </uni-collapse>
  62. </view>
  63. </template>
  64. <script setup lang="ts">
  65. import { onMounted, ref } from 'vue';
  66. const current = ref(0)
  67. const props = defineProps({
  68. anime: { type: Boolean, default: false }, // 是否开启动画
  69. open: { type: Boolean, default: false }, // 是否默认打开
  70. title: { type: String, required: true }, // 标题
  71. segments: { type: Array, default: undefined }, // 分段器数据
  72. list: { type: Array, required: true }, // 消息数据
  73. pSize: { type: Number, default: 10 }, // 分页大小
  74. pageNo: { type: Number, default: 1 }, // 默认页
  75. unReadNum: { type: Number, default: undefined }, // 未读消息数
  76. })
  77. const emits = defineEmits([
  78. 'clickSegment', // 点击分段器
  79. 'clickItem', // 点击内容项
  80. 'scrollToBottom' // 到达底部
  81. ])
  82. // 分段器 键值
  83. const segmentKeys = ref({})
  84. const segmentValues = ref({})
  85. onMounted(() => {
  86. if (props.segments !== undefined) {
  87. segmentKeys.value = Object.keys(props.segments)
  88. segmentValues.value = Object.values(props.segments)
  89. }
  90. })
  91. const paging = ref(null)
  92. // 加载完成 更新数据
  93. function complete(list, total, pageNo) {
  94. // 第一页直接加载数据
  95. if (pageNo === 1) {
  96. paging.value.complete(list)
  97. return
  98. }
  99. // 防止重复获取最后一次信息
  100. if (props.pSize*pageNo < total) {
  101. paging.value.complete(list)
  102. } else {
  103. paging.value.complete([])
  104. }
  105. }
  106. // 点击分段器
  107. function onClickItem({ currentIndex }) {
  108. current.value = currentIndex
  109. // 重新加载数据 pageNo恢复为默认值
  110. paging.value.reload()
  111. }
  112. // 刷新
  113. function queryData(pageNo, pSize, queryType) {
  114. switch (queryType) {
  115. case 0: // 下拉刷新
  116. case 1: // 初始加载
  117. reloadData()
  118. break
  119. case 3: // 上拉加载
  120. scrollQuery(pageNo, pSize)
  121. break
  122. default: // 默认刷新
  123. reloadData()
  124. break
  125. }
  126. }
  127. // 刷新数据
  128. function reloadData() {
  129. const params = {
  130. pSize: props.pSize,
  131. pageNo: props.pageNo,
  132. type: '',
  133. segmentValue: segmentValues.value[current.value]
  134. }
  135. emits('clickSegment', params, complete)
  136. }
  137. // 上拉加载
  138. function scrollQuery(pageNo, pSize) {
  139. const params = {
  140. pSize,
  141. pageNo,
  142. type: '',
  143. segmentValue: segmentValues.value[current.value]
  144. }
  145. emits('scrollToBottom', params, complete)
  146. }
  147. // 跳转详情
  148. function handleToDetail(message) {
  149. emits('clickItem', message)
  150. }
  151. </script>
  152. <style lang="scss" scoped>
  153. .hidden_over {
  154. white-space: nowrap; // 不换行
  155. overflow: hidden; // 超出内容隐藏
  156. text-overflow: ellipsis; // 超出部分显示省略号
  157. display: inline-block;
  158. max-width: 100%;
  159. }
  160. .msg_list_content {
  161. .message_container {
  162. border-left: #7b7b7b .4rem solid;
  163. .message_top_container {
  164. padding: 10px 10px 10px;
  165. .message_user {
  166. color: #333;
  167. font-size: 0.875rem;
  168. }
  169. }
  170. .message_mid_container {
  171. // padding-top: 10px;
  172. padding-left: 10px;
  173. height: 1.8rem;
  174. .message_title {
  175. font-size: 1.1rem;
  176. color: #333;
  177. }
  178. .message_time {
  179. color: #888;
  180. text-align: right;
  181. font-size: 0.8rem;
  182. }
  183. }
  184. .message_bottom_container {
  185. .message_content {
  186. font-size: 1rem;
  187. color: #666;
  188. }
  189. }
  190. }
  191. .message_container_unread {
  192. // 未读样式
  193. border-left-color: #0f6cbd;
  194. .message_top_container {
  195. .message_user {
  196. font-weight: bold;
  197. }
  198. }
  199. .message_mid_container {
  200. .message_title {
  201. color: #0f6cbd;
  202. font-weight: bold;
  203. }
  204. }
  205. }
  206. }
  207. </style>