Explorar o código

feat(messages): 添加消息卡组件以展示积分券信息

EvilDragon hai 5 meses
pai
achega
2154938951

+ 162 - 0
packages/app/src/pages/messages/components/message-card.vue

@@ -0,0 +1,162 @@
+<script setup lang="ts">
+import { Message } from '../../../core/libs/models'
+import Card from '@/components/card.vue'
+import { integral, interact, message, system } from '../../../core/libs/svgs'
+import { beforeNow } from '../../../utils/date-util'
+import dayjs from 'dayjs'
+import { MessageType } from '../../../core/libs/enums'
+import { getPointsCoupons } from '../../../core/libs/requests'
+
+const props = withDefaults(defineProps<{ options?: Message }>(), {})
+const emits = defineEmits<{
+  submit: [message: Message]
+  cancel: [message: Message]
+  selectCoupon: [coupons: any[]]
+}>()
+const { data: coupons, run: setCoupons } = useRequest(() =>
+  getPointsCoupons({ userId: props.options.designerId, businessId: props.options.businessId }),
+)
+onMounted(async () => {
+  if (
+    props.options.messageType === MessageType.Integral &&
+    props.options.messageSubType === 31 &&
+    props.options.isRead !== '1'
+  ) {
+    await setCoupons()
+    // console.log(coupons.value)
+  }
+})
+</script>
+<template>
+  <Card>
+    <div class="grid items-center grid-cols-[38px_auto_100px]">
+      <div class="row-start-1 col-start-1">
+        <div
+          class="w-[30px] h-[30px] bg-neutral-100 rounded-full mr-2 flex items-center justify-center"
+        >
+          <wd-img
+            width="18"
+            height="18"
+            :src="
+              {
+                [MessageType.Integral]: integral,
+                [MessageType.System]: system,
+                [MessageType.Interact]: interact,
+              }[options.messageType]
+            "
+          ></wd-img>
+        </div>
+      </div>
+      <div class="row-start-1 col-start-2 text-start">
+        <div class="text-black/90 text-base font-normal font-['PingFang_SC'] leading-[30px]">
+          {{ options.title }}
+        </div>
+      </div>
+      <div class="row-start-1 col-start-3 text-end">
+        <div class="text-black/30 text-sm font-normal font-['PingFang_SC'] leading-[10.18px]">
+          {{ beforeNow(dayjs(options.createTime).toDate()) }}
+        </div>
+      </div>
+      <div class="row-start-2 col-start-2 col-end-4">
+        <div class="my-3 text-black/40 text-sm font-normal font-['PingFang_SC'] leading-[25px]">
+          <div
+            v-if="options.messageType === MessageType.Integral"
+            v-html="options.detailBody"
+          ></div>
+          <div class="grid grid-cols-[auto_1fr] gap-x-5 gap-y-4.5">
+            <template v-if="options.messageSubType === 31 && options.isRead !== '1'">
+              <div
+                class="text-black/40 text-sm font-normal font-['PingFang_SC'] h-5.5 flex items-center"
+              >
+                积分券
+              </div>
+              <div
+                class="flex items-center"
+                @click="coupons.length && emits('selectCoupon', coupons)"
+              >
+                <div
+                  class="text-sm font-normal font-['PingFang_SC']"
+                  :class="`${coupons.length > 0 ? 'text-[#ef4343]' : 'text-black/60'}`"
+                >
+                  {{ `${coupons.length > 0 ? `${coupons.length}张可用` : '无可用'}` }}
+                </div>
+                <div class="h-5.5 overflow-hidden">
+                  <wd-icon
+                    name="chevron-right"
+                    :custom-class="`${coupons.length > 0 ? 'text-[#ef4343]' : 'text-black/60'}`"
+                    size="20"
+                  ></wd-icon>
+                </div>
+              </div>
+            </template>
+          </div>
+          <!-- {{ options.detailBody }} -->
+        </div>
+      </div>
+      <div v-if="options.coverUrl" class="row-start-3 col-start-2 col-end-4">
+        <img class="w-[279px] h-[164px] rounded-md" :src="options.coverUrl" />
+      </div>
+      <div class="row-start-4 col-start-1 col-end-4 my-2">
+        <div v-if="!options.coverUrl" class="bg-[#dadada] w-full h-[1px]"></div>
+      </div>
+      <div class="row-start-5 col-start-2 col-end-4">
+        <div class="text-black/40 text-xs font-normal font-['PingFang_SC']">
+          <template
+            v-if="
+              [MessageType.Integral].includes(Number(options.messageType)) &&
+              options.messageSubType === 31 &&
+              options.isRead !== '1'
+            "
+          >
+            <span class="text-black/40">
+              确认积分后,即刻到账,如有问题请驳回,联系材料商修改积分后再次确认
+            </span>
+          </template>
+          <template
+            v-else-if="
+              [MessageType.Integral].includes(Number(options.messageType)) && options.isRead === '1'
+            "
+          >
+            <span class="text-black/40">
+              <!-- 确认积分后,即刻到账,如有问题请驳回,联系材料商修改积分后再次确认 -->
+            </span>
+          </template>
+          <template
+            v-else-if="
+              [MessageType.Integral].includes(Number(options.messageType)) &&
+              [21, 22].includes(options.messageSubType)
+            "
+          >
+            如有问题请您联系官方客服!
+          </template>
+          <template v-else>
+            <div class="flex items-center text-black">
+              查看详情
+              <wd-icon name="arrow-right" size="16"></wd-icon>
+            </div>
+          </template>
+        </div>
+      </div>
+      <div
+        class="row-start-6 col-start-1 col-end-4 my-1"
+        v-if="
+          [MessageType.Integral].includes(Number(options.messageType)) &&
+          options.messageSubType === 31 &&
+          options.isRead !== '1'
+        "
+      >
+        <div class="flex gap-4">
+          <div class="flex-1">
+            <wd-button block :round="false" plain @click="emits('cancel', options)">驳回</wd-button>
+          </div>
+          <!-- <div class="flex-1">
+            <wd-button block :round="false" @click="handleQ(it)">积分券</wd-button>
+          </div> -->
+          <div class="flex-1">
+            <wd-button block :round="false" @click="emits('submit', options)">确认</wd-button>
+          </div>
+        </div>
+      </div>
+    </div>
+  </Card>
+</template>

+ 19 - 144
packages/app/src/pages/messages/index.vue

@@ -9,7 +9,6 @@
 </route>
 
 <script setup lang="ts">
-import Card from '@/components/card.vue'
 import PageHelper from '@/components/page-helper.vue'
 import {
   deleteMessage,
@@ -19,21 +18,19 @@ import {
   orderPointsSubmit,
   updateMessage,
 } from '../../core/libs/requests'
-import { integral, interact, message, system } from '../../core/libs/svgs'
-import { beforeNow } from '../../utils/date-util'
 import dayjs from 'dayjs'
 import { MessageType } from '../../core/libs/enums'
 import { ComponentExposed } from 'vue-component-type-helpers'
-import { Message } from '../../core/libs/models'
+import { Coupon, Message } from '../../core/libs/models'
 import { requestToast } from '../../core/utils/common'
 import { useUserStore } from '../../store'
 import { storeToRefs } from 'pinia'
+import MessageCard from './components/message-card.vue'
 
 const pageHelperRef = ref<ComponentExposed<typeof PageHelper>>()
 const userStore = useUserStore()
 const { userInfo } = storeToRefs(userStore)
 const show = ref(false)
-const businessId = ref()
 const tab = ref(0)
 const tabs = ref([
   { label: '积分消息', value: MessageType.Integral },
@@ -41,14 +38,9 @@ const tabs = ref([
   { label: '互动消息', value: MessageType.Interact },
 ])
 const selectedCoupon = ref()
-const { data: coupons, run: setCoupons } = useRequest(() =>
-  getPointsCoupons({ userId: userInfo.value.userId, businessId: businessId.value }),
-)
-onShow(async () => {
-  nextTick(() => {
-    pageHelperRef.value?.refresh()
-  })
-})
+const coupons = ref<Coupon[]>([])
+const query = computed(() => ({ messageType: tabs[tab.value]?.value }))
+
 const handleCancel = async (message: Message) => {
   await requestToast(
     () => orderPointsCancel({ id: message.businessId.toString(), cancelReason: '用户取消' }),
@@ -75,16 +67,20 @@ const handleSubmit = async (message: Message) => {
   await updateMessage({ id: message.id, isRead: '1' })
   await pageHelperRef.value?.refresh()
 }
-const handleQ = async (message: Message) => {
+const handleQ = async (res) => {
   // const { data } = await getPointsCoupons({
   //   userId: message.designerId,
   //   businessId: message.businessId,
   // })
   // console.log(data)
-  businessId.value = message.businessId
-  await setCoupons()
+  coupons.value = res
   show.value = true
 }
+onShow(async () => {
+  nextTick(() => {
+    pageHelperRef.value?.refresh()
+  })
+})
 </script>
 
 <template>
@@ -98,139 +94,18 @@ const handleQ = async (message: Message) => {
       ref="pageHelperRef"
       :automatic="false"
       :request="getMessages"
-      :query="{ messageType: tabs[tab]?.value }"
+      :query="query"
       class="flex-grow flex flex-col"
     >
       <template #default="{ source }">
         <div class="p-3.5 gap-3.5 flex flex-col">
           <template v-for="(it, i) in source.list" :key="i">
-            <Card>
-              <div class="grid items-center grid-cols-[38px_auto_100px]">
-                <div class="row-start-1 col-start-1">
-                  <div
-                    class="w-[30px] h-[30px] bg-neutral-100 rounded-full mr-2 flex items-center justify-center"
-                  >
-                    <wd-img
-                      width="18"
-                      height="18"
-                      :src="[integral, system, interact][tab]"
-                    ></wd-img>
-                  </div>
-                </div>
-                <div class="row-start-1 col-start-2 text-start">
-                  <div
-                    class="text-black/90 text-base font-normal font-['PingFang_SC'] leading-[30px]"
-                  >
-                    {{ it.title }}
-                  </div>
-                </div>
-                <div class="row-start-1 col-start-3 text-end">
-                  <div
-                    class="text-black/30 text-sm font-normal font-['PingFang_SC'] leading-[10.18px]"
-                  >
-                    {{ beforeNow(dayjs(it.createTime).toDate()) }}
-                  </div>
-                </div>
-                <div class="row-start-2 col-start-2 col-end-4">
-                  <div
-                    class="my-3 text-black/40 text-sm font-normal font-['PingFang_SC'] leading-[25px]"
-                  >
-                    <div
-                      v-if="it.messageType === MessageType.Integral"
-                      v-html="it.detailBody"
-                    ></div>
-                    <div class="grid grid-cols-[auto_1fr] gap-x-5 gap-y-4.5">
-                      <template v-if="true">
-                        <div
-                          class="text-black/40 text-sm font-normal font-['PingFang_SC'] h-5.5 flex items-center"
-                        >
-                          积分券
-                        </div>
-                        <div class="flex items-center">
-                          <div class="text-black/60 text-sm font-normal font-['PingFang_SC']">
-                            无可用
-                          </div>
-                          <div class="h-5.5 overflow-hidden">
-                            <wd-icon
-                              name="chevron-right"
-                              custom-class="text-black/60!"
-                              size="20"
-                            ></wd-icon>
-                          </div>
-                        </div>
-                      </template>
-                    </div>
-                    <!-- {{ it.detailBody }} -->
-                  </div>
-                </div>
-                <div v-if="it.coverUrl" class="row-start-3 col-start-2 col-end-4">
-                  <img class="w-[279px] h-[164px] rounded-md" :src="it.coverUrl" />
-                </div>
-                <div class="row-start-4 col-start-1 col-end-4 my-2">
-                  <div v-if="!it.coverUrl" class="bg-[#dadada] w-full h-[1px]"></div>
-                </div>
-                <div class="row-start-5 col-start-2 col-end-4">
-                  <div class="text-black/40 text-xs font-normal font-['PingFang_SC']">
-                    <template
-                      v-if="
-                        [MessageType.Integral].includes(Number(it.messageType)) &&
-                        it.messageSubType === 31 &&
-                        it.isRead !== '1'
-                      "
-                    >
-                      <span class="text-black/40">
-                        确认积分后,即刻到账,如有问题请驳回,联系材料商修改积分后再次确认
-                      </span>
-                    </template>
-                    <template
-                      v-else-if="
-                        [MessageType.Integral].includes(Number(it.messageType)) && it.isRead === '1'
-                      "
-                    >
-                      <span class="text-black/40">
-                        <!-- 确认积分后,即刻到账,如有问题请驳回,联系材料商修改积分后再次确认 -->
-                      </span>
-                    </template>
-                    <template
-                      v-else-if="
-                        [MessageType.Integral].includes(Number(it.messageType)) &&
-                        it.messageSubType === 22
-                      "
-                    >
-                      如有问题请您联系官方客服!
-                    </template>
-                    <template v-else>
-                      <div class="flex items-center text-black">
-                        查看详情
-                        <wd-icon name="arrow-right" size="16"></wd-icon>
-                      </div>
-                    </template>
-                  </div>
-                </div>
-                <div
-                  class="row-start-6 col-start-1 col-end-4 my-1"
-                  v-if="
-                    [MessageType.Integral].includes(Number(it.messageType)) &&
-                    it.messageSubType === 31 &&
-                    it.isRead !== '1'
-                  "
-                >
-                  <div class="flex gap-4">
-                    <div class="flex-1">
-                      <wd-button block :round="false" plain @click="handleCancel(it)">
-                        驳回
-                      </wd-button>
-                    </div>
-                    <div class="flex-1">
-                      <wd-button block :round="false" @click="handleQ(it)">积分券</wd-button>
-                    </div>
-                    <div class="flex-1">
-                      <wd-button block :round="false" @click="handleSubmit(it)">确认</wd-button>
-                    </div>
-                  </div>
-                </div>
-              </div>
-            </Card>
+            <MessageCard
+              :options="it"
+              @submit="handleSubmit"
+              @cancel="handleCancel"
+              @select-coupon="handleQ"
+            ></MessageCard>
           </template>
         </div>
       </template>