message-card.vue 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <script setup lang="ts">
  2. import { Coupon, Message } from '../../../core/libs/models'
  3. import Card from '@/components/card.vue'
  4. import { integral, interact, message, system } from '../../../core/libs/svgs'
  5. import { beforeNow } from '../../../utils/date-util'
  6. import dayjs from 'dayjs'
  7. import { MessageType, PointStatus } from '../../../core/libs/enums'
  8. import { fuckYou, getPointsCoupons, updateReadByMessageType } from '../../../core/libs/requests'
  9. import { getMessageType } from '../../../core/libs/message-types'
  10. import { useRouter } from '../../../core/utils/router'
  11. import ButtonEvo from '@/components/button-evo.vue'
  12. import { messages } from '../../../core/libs/messages'
  13. import { stringify } from 'qs'
  14. const props = withDefaults(
  15. defineProps<{ options?: Message & { selectedCoupons?: Coupon[] } }>(),
  16. {},
  17. )
  18. const emits = defineEmits<{
  19. submit: [message: Message, coupons: Coupon[]]
  20. cancel: [message: Message]
  21. selectCoupon: [message: Message, coupons: any[]]
  22. }>()
  23. const router = useRouter()
  24. const { data: coupons, run: setCoupons } = useRequest(
  25. () =>
  26. getPointsCoupons({
  27. userId: props.options.designerId,
  28. businessId: props.options.businessId,
  29. available: true,
  30. }),
  31. { initialData: [] },
  32. )
  33. const couponSelectText = computed(() => {
  34. const selectedCoupons = props.options.selectedCoupons || []
  35. const availableCoupons = props.options.availableCouponsNum || 0
  36. console.log('selectedCoupons computed', selectedCoupons)
  37. if (selectedCoupons.length > 0) {
  38. return `${selectedCoupons[0].brandPoints ?? 0}积分`
  39. }
  40. if (availableCoupons > 0) {
  41. return `${availableCoupons}张可用`
  42. }
  43. return '无可用'
  44. })
  45. const hasLine = computed(() => getMessageType(props.options.messageSubType)?.path)
  46. const init = async () => {
  47. if (
  48. props.options.messageType === MessageType.Integral &&
  49. props.options.messageSubType === 31 &&
  50. props.options.isRead !== '1'
  51. ) {
  52. await setCoupons()
  53. }
  54. }
  55. const handleJump = () => {
  56. fuckYou({ id: props.options.id })
  57. if ((props.options.linkUrl ?? '') !== '') {
  58. return router.push(props.options.linkUrl)
  59. }
  60. const query: Record<string, string> = {}
  61. switch (props.options.messageSubType) {
  62. case 5:
  63. query.id = props.options.id as any
  64. query.title = props.options.title
  65. query.contentDetail = props.options.detailBody
  66. query.createTime = String(props.options.createTime)
  67. query.viewsCount = props.options.viewCount
  68. break
  69. case 14:
  70. query.type = props.options.couponType
  71. default:
  72. break
  73. }
  74. console.log(stringify(query))
  75. router.push(getMessageType(props.options.messageSubType)?.path + '?' + stringify(query))
  76. }
  77. watch(
  78. () => props.options,
  79. async (value, oldValue, onCleanup) => {
  80. // console.log('====>', value)
  81. await init()
  82. },
  83. )
  84. onMounted(async () => {
  85. await init()
  86. })
  87. </script>
  88. <template>
  89. <Card>
  90. <div class="grid items-center grid-cols-[38px_auto_100px]">
  91. <div class="row-start-1 col-start-1">
  92. <div
  93. class="w-[30px] h-[30px] bg-neutral-100 rounded-full mr-2 flex items-center justify-center"
  94. >
  95. <wd-img
  96. width="18"
  97. height="18"
  98. :src="
  99. {
  100. [MessageType.Integral]: integral,
  101. [MessageType.System]: system,
  102. [MessageType.Interact]: interact,
  103. }[options.messageType]
  104. "
  105. ></wd-img>
  106. </div>
  107. </div>
  108. <div class="row-start-1 col-start-2 text-start relative">
  109. <div class="text-black/90 text-base font-normal font-['PingFang_SC'] leading-[30px]">
  110. <!-- {{-->
  111. <!-- String(options.messageSubType) === '5'-->
  112. <!-- ? getMessageType(options.messageSubType)?.desc-->
  113. <!-- : options.title-->
  114. <!-- }}-->
  115. {{ options.title }}
  116. </div>
  117. </div>
  118. <div class="row-start-1 col-start-3 text-end" style="white-space: nowrap">
  119. <div class="text-black/30 text-sm font-normal font-['PingFang_SC'] leading-[8.18px]">
  120. <template v-if="String(options.isRead) === '0'">
  121. <wd-img width="16" height="16" src="/static/svgs/red.svg"></wd-img>
  122. </template>
  123. {{ beforeNow(dayjs(options.createTime).toDate()) }}
  124. <!-- <div class="absolute top-[2px] right-[50px] z-10">-->
  125. <!-- <wd-img width="16" height="20" src="/static/svgs/red.svg"></wd-img>-->
  126. <!-- </div>-->
  127. <!-- <wd-img width="16" height="10" src="/static/svgs/red.svg"></wd-img>-->
  128. </div>
  129. </div>
  130. <div class="row-start-2 col-start-2 col-end-4">
  131. <div class="my-3 text-black/40 text-sm font-normal font-['PingFang_SC'] leading-[25px]">
  132. <!-- {{ options.detailBody }} -->
  133. <!-- <div-->
  134. <!-- v-if="-->
  135. <!-- [MessageType.Integral, MessageType.System].includes(options.messageType) &&-->
  136. <!-- String(options.messageSubType) !== '5'-->
  137. <!-- "-->
  138. <!-- v-html="options.detailBody"-->
  139. <!-- ></div>-->
  140. <div v-html="options.detailBody"></div>
  141. <div class="grid grid-cols-[auto_1fr] gap-x-1 gap-y-4.5">
  142. <template
  143. v-if="
  144. options.messageSubType === 31 &&
  145. options.pointsDetail?.pointsStauts === PointStatus.PendingConfirmation
  146. "
  147. >
  148. <div
  149. class="text-black/40 text-sm font-normal font-['PingFang_SC'] h-5.5 flex items-center"
  150. >
  151. 销售积分券:
  152. </div>
  153. <div
  154. class="flex items-center h-full overflow-hidden"
  155. @click="emits('selectCoupon', options, coupons)"
  156. >
  157. <div
  158. class="text-sm font-normal font-['PingFang_SC']"
  159. :class="`${coupons.length > 0 ? 'text-[#ef4343]' : 'text-black/60'}`"
  160. >
  161. <!-- {{ `${coupons.length > 0 ? `${coupons.length}张可用` : '无可用'}` }}-->
  162. {{ couponSelectText }}
  163. </div>
  164. <div class="h-5.5 flex items-center overflow-hidden">
  165. <wd-icon
  166. name="chevron-right"
  167. :custom-class="`${coupons.length > 0 ? 'text-[#ef4343]' : 'text-black/60'}`"
  168. size="16"
  169. ></wd-icon>
  170. </div>
  171. </div>
  172. </template>
  173. </div>
  174. </div>
  175. </div>
  176. <div
  177. v-if="options.coverUrl"
  178. class="row-start-3 col-start-2 col-end-4 aspect-[1.7/1] rounded-md overflow-hidden"
  179. >
  180. <wd-img
  181. width="100%"
  182. height="100%"
  183. mode="aspectFill"
  184. :src="options.coverUrl"
  185. @click="handleJump"
  186. />
  187. </div>
  188. <div v-if="hasLine" class="row-start-4 col-start-1 col-end-4 my-2">
  189. <div class="bg-[#dadada] w-full h-[1px]"></div>
  190. </div>
  191. <div class="row-start-5 col-start-2 col-end-4">
  192. <div class="text-black/40 text-xs font-normal font-['PingFang_SC']">
  193. <template
  194. v-if="
  195. [MessageType.Integral].includes(Number(options.messageType)) &&
  196. options.messageSubType === 31 &&
  197. options.pointsDetail?.pointsStauts === PointStatus.PendingConfirmation
  198. "
  199. >
  200. <span class="text-black/40">
  201. {{ messages.messages.pointNotice }}
  202. </span>
  203. </template>
  204. <template
  205. v-else-if="
  206. [MessageType.Integral].includes(Number(options.messageType)) &&
  207. options.messageSubType === 31
  208. "
  209. >
  210. <template v-if="options.pointsDetail?.pointsStauts === PointStatus.Rejected">
  211. <span class="text-[#EF4343]">
  212. <!-- 确认积分后,即刻到账,如有问题请驳回,联系材料商修改积分后再次确认 -->
  213. 已驳回,驳回原因:{{ options.pointsDetail?.cancelReason }}
  214. </span>
  215. </template>
  216. </template>
  217. <template
  218. v-else-if="
  219. [MessageType.Integral].includes(Number(options.messageType)) &&
  220. [21, 22].includes(options.messageSubType)
  221. "
  222. >
  223. 如有问题请您联系官方客服!
  224. </template>
  225. <template v-if="getMessageType(options.messageSubType)?.path">
  226. <div
  227. @click="handleJump"
  228. class="flex items-center text-[rgba(0,0,0,0.85)] text-xs font-normal font-['PingFang_SC'] leading-[25px]"
  229. >
  230. 查看详情
  231. <wd-icon name="arrow-right" size="12" color="rgba(0,0,0,0.85)"></wd-icon>
  232. </div>
  233. </template>
  234. </div>
  235. </div>
  236. <div
  237. class="row-start-6 col-start-1 col-end-4 my-1"
  238. v-if="
  239. [MessageType.Integral].includes(Number(options.messageType)) &&
  240. options.messageSubType === 31 &&
  241. options.pointsDetail?.pointsStauts === PointStatus.PendingConfirmation
  242. "
  243. >
  244. <div class="flex gap-4 mt-4">
  245. <div class="flex-1">
  246. <!-- <wd-button block :round="false" plain @click="emits('cancel', options)">驳回</wd-button> -->
  247. <ButtonEvo block color="white" location="right" @click="emits('cancel', options)">
  248. <span class="text-black/80">驳回</span>
  249. </ButtonEvo>
  250. </div>
  251. <!-- <div class="flex-1">
  252. <wd-button block :round="false" @click="handleQ(it)">积分券</wd-button>
  253. </div> -->
  254. <div class="flex-1">
  255. <!-- <wd-button block :round="false" @click="emits('submit', options)">确认</wd-button> -->
  256. <ButtonEvo block @click="emits('submit', options, coupons)">确认</ButtonEvo>
  257. </div>
  258. </div>
  259. </div>
  260. </div>
  261. </Card>
  262. </template>