listCard.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <script setup lang="ts">
  2. import dayjs from "dayjs"
  3. import "dayjs/locale/zh-cn" // 导入本地化语言
  4. import route from "@/route"
  5. import configs from "@/core/config"
  6. dayjs.locale("zh-cn") // 使用本地化语言
  7. const props = withDefaults(
  8. defineProps<{
  9. type: string
  10. item: any
  11. map: { id: string; date: string }
  12. }>(),
  13. {
  14. item: () => {
  15. return {}
  16. },
  17. map: () => {
  18. return {
  19. id: "id",
  20. date: "date",
  21. }
  22. },
  23. }
  24. )
  25. const emits = defineEmits<{
  26. (e: "click", item: any): void
  27. }>()
  28. const isActivity = computed(() => {
  29. return props.type && props.type.search("activity") >= 0
  30. })
  31. const isHelp = computed(() => {
  32. return props.type && props.type.search("help") >= 0
  33. })
  34. const isNews = computed(() => {
  35. return props.type && props.type.search("news") >= 0
  36. })
  37. const isHot = computed(() => {
  38. return props.item.isHot == "1" || props.item.readCount > 50
  39. })
  40. const content = computed(() => {
  41. if (props.item.content) {
  42. const len = props.item.images ? 55 : 80
  43. return props.item.content.length > len
  44. ? props.item.content.replace(/<[^>]+>/g, "").substring(0, len) + "..."
  45. : props.item.content
  46. }
  47. return ""
  48. })
  49. const image = computed(() => {
  50. if (props.item.images) {
  51. const arr = props.item.images.split(",")
  52. return `${configs.baseUrl}/oss/preview/${arr[0]}`
  53. }
  54. return ""
  55. })
  56. const date = computed(() => {
  57. return dayjs(new Date(props.item[props.map.date])).format("YYYY-MM-DD ddd")
  58. })
  59. const statusClass = computed(() => {
  60. if (props.item.isClose == "1" || props.item.auditStatus == "2") {
  61. return "bg-danger"
  62. }
  63. if (dayjs(props.item.expiryDate).isBefore(new Date())) {
  64. return "bg-warning"
  65. }
  66. if (props.item.auditStatus == "0") {
  67. return "bg-gray-5"
  68. }
  69. if (props.item.auditStatus == "1") {
  70. return "bg-vb"
  71. }
  72. return ""
  73. })
  74. const statusName = computed(() => {
  75. if (props.item.isClose == "1") {
  76. return "已结束"
  77. }
  78. if (dayjs(props.item.expiryDate).isBefore(new Date())) {
  79. return "已过期"
  80. }
  81. if (props.item.auditStatus == "0") {
  82. return "审核中"
  83. }
  84. if (props.item.auditStatus == "1") {
  85. return isActivity.value ? "报名中" : isHelp.value ? "互助中" : ""
  86. }
  87. if (props.item.auditStatus == "2") {
  88. return "未通过"
  89. }
  90. return ""
  91. })
  92. function onClick(item: any) {
  93. emits("click", item)
  94. route.navigate(props.type as any, { id: item[props.map.id] })
  95. }
  96. function init() {
  97. //
  98. }
  99. onMounted(init)
  100. </script>
  101. <template>
  102. <vb-cell-group custom-class="">
  103. <view class="flex-column p-15 pos-r" @click="onClick(item)">
  104. <view
  105. v-if="!isNews"
  106. class="pos-a px-8 py-3 fs-12 text-white"
  107. :class="statusClass"
  108. style="top: 0; right: 0; border-radius: 0 0 0 var(--vb-cell-group-radius)"
  109. >
  110. {{ statusName }}
  111. </view>
  112. <view class="pb-5 pt-2 d-flex">
  113. <vb-icon v-if="isHot" name="hot" :size="30" custom-class="text-danger"></vb-icon>
  114. <view class="fs-20 font-bold">{{ item.title }}</view>
  115. <vb-icon v-if="item.isHead == '1'" name="head" :size="30" custom-class="text-vb"></vb-icon>
  116. </view>
  117. <view class="d-flex py-5 ps-5">
  118. <view class="text-vb pe-20">{{ item.categoryName }}</view>
  119. <view class="d-fcv text-gray-5">
  120. <i class="iconfont icon-home text-gray-5 pe-5 fs-20"></i>
  121. {{ item.isSys == "1" || isNews ? "平台发布" : item.createdBy + " 发布" }}
  122. </view>
  123. </view>
  124. <view class="d-flex py-5">
  125. <view class="text-gray-8 w-100 me-10 text-indent">
  126. {{ content }}
  127. </view>
  128. <view v-if="item.images" class="w-150px h-80px">
  129. <image class="w-100 h-100 br-8" :src="image" :lazy-load="true" mode="aspectFill"></image>
  130. </view>
  131. </view>
  132. <view class="pt-10 d-flex justify-between">
  133. <view class="d-flex">
  134. <view class="px-10 d-fcv text-gray-5">
  135. <i class="iconfont icon-eye text-gray-5 pe-5 fs-20"></i>
  136. {{ item.readCount || 0 }}
  137. </view>
  138. <view class="px-10 d-fcv text-gray-5">
  139. <i class="iconfont icon-chat text-gray-5 pe-5 fs-20"></i>
  140. {{ item.commentCount || 0 }}
  141. </view>
  142. </view>
  143. <view class="px-10 d-fcv text-gray-5">
  144. <i class="iconfont icon-calendar text-gray-5 pe-5 fs-20"></i>
  145. {{ date }}
  146. </view>
  147. </view>
  148. </view>
  149. </vb-cell-group>
  150. </template>