messageList.vue 5.8 KB

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