knowledgeList.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. <template>
  2. <div class="service-records-page">
  3. <custom-header name="知识库"></custom-header>
  4. <div class="record-list">
  5. <list
  6. v-model:loading="listLoading"
  7. :finished="listFinished"
  8. finished-text=""
  9. @load="getKnowledgeList"
  10. >
  11. <div v-for="(item, index) in knowledgeList" :key="index" class="record-card">
  12. <img class="thumb" :src="item.media && item.media[0]" alt="暂无图片" />
  13. <div class="card-body" @click="handleItemClick(item)">
  14. <div class="card-body-left">
  15. <div class="title van-multi-ellipsis--l2">{{ item.title }}</div>
  16. <div class="date">{{ formatDate(item.createTime) }}</div>
  17. </div>
  18. </div>
  19. </div>
  20. <!-- 加载完成且无数据时的空状态 -->
  21. <div v-if="!knowledgeList.length && listFinished" class="empty-wrap">
  22. <div class="empty-text">暂无数据</div>
  23. </div>
  24. </list>
  25. </div>
  26. </div>
  27. </template>
  28. <script setup>
  29. import { ref, onMounted } from "vue";
  30. import customHeader from "@/components/customHeader.vue";
  31. import { List } from "vant";
  32. import { useRouter, useRoute } from "vue-router";
  33. const router = useRouter();
  34. const route = useRoute();
  35. // 服务记录列表数据
  36. const knowledgeList = ref([]);
  37. const topicId = ref(6);
  38. // 分页与滚动加载状态
  39. const page = ref(1);
  40. const pageSize = ref(10);
  41. const listLoading = ref(false);
  42. const listFinished = ref(false);
  43. onMounted(() => {
  44. // 从路由获取当前知识库类型
  45. topicId.value = route.query.topicId || 6;
  46. // 不主动请求,交给 vant List 的 @load 触发首次加载
  47. });
  48. const getKnowledgeList = async () => {
  49. if (listFinished.value) return;
  50. listLoading.value = true;
  51. const params = {
  52. page: page.value,
  53. limit: pageSize.value,
  54. topicId: topicId.value,
  55. };
  56. try {
  57. const { data } = await VE_API.home.warningPageList(params);
  58. const list = data || [];
  59. if (page.value === 1) {
  60. knowledgeList.value = list;
  61. } else {
  62. knowledgeList.value = [...knowledgeList.value, ...list];
  63. }
  64. // 如果返回数量小于页大小,认为没有更多数据了
  65. if (list.length < pageSize.value) {
  66. listFinished.value = true;
  67. } else {
  68. page.value += 1;
  69. }
  70. } finally {
  71. listLoading.value = false;
  72. }
  73. };
  74. const formatDate = (dateStr) => {
  75. if (!dateStr) return "";
  76. // 将 2026-01-06T00:00:00 格式转换为 2026-01-06
  77. return dateStr.split("T")[0];
  78. };
  79. const handleItemClick = (item) => {
  80. router.push(`/warning_detail?id=${item.id}`);
  81. };
  82. </script>
  83. <style lang="scss" scoped>
  84. .service-records-page {
  85. width: 100%;
  86. min-height: 100vh;
  87. background: #f5f5f5;
  88. .record-list {
  89. padding: 10px 12px;
  90. display: flex;
  91. flex-direction: column;
  92. gap: 10px;
  93. }
  94. .record-card {
  95. display: flex;
  96. gap: 12px;
  97. padding: 12px 10px;
  98. background: #ffffff;
  99. border-radius: 12px;
  100. align-items: center;
  101. height: 98px;
  102. box-sizing: border-box;
  103. .thumb {
  104. width: 112px;
  105. height: 74px;
  106. border-radius: 8px;
  107. object-fit: cover;
  108. flex: none;
  109. }
  110. .card-body {
  111. flex: 1;
  112. height: 100%;
  113. display: flex;
  114. align-items: center;
  115. justify-content: space-between;
  116. .card-body-left {
  117. width: 100%;
  118. height: 95%;
  119. display: flex;
  120. flex-direction: column;
  121. justify-content: space-between;
  122. .date {
  123. font-size: 13px;
  124. color: #86909c;
  125. margin-top: 4px;
  126. }
  127. }
  128. }
  129. }
  130. .empty-wrap {
  131. padding-top: 40px;
  132. text-align: center;
  133. .empty-text {
  134. font-size: 14px;
  135. color: #86909c;
  136. }
  137. }
  138. }
  139. </style>