Forráskód Böngészése

【优化】mall 客服商品消息

puhui999 9 hónapja
szülő
commit
ebc995ac4c

+ 36 - 0
src/views/mall/promotion/kefu/components/message/OrderMessageItem.vue

@@ -0,0 +1,36 @@
+<template>
+  <!-- 图片消息 -->
+  <template v-if="KeFuMessageContentTypeEnum.PRODUCT === message.contentType">
+    <div
+      :class="[
+        message.senderType === UserTypeEnum.MEMBER
+          ? `ml-10px`
+          : message.senderType === UserTypeEnum.ADMIN
+            ? `mr-10px`
+            : ''
+      ]"
+    >
+      <ProductItem
+        :img="getMessageContent.picUrl"
+        :price="getMessageContent.price"
+        :skuText="getMessageContent.introduction"
+        :title="getMessageContent.spuName"
+        :titleWidth="400"
+        priceColor="#FF3000"
+      />
+    </div>
+  </template>
+</template>
+
+<script lang="ts" setup>
+import { KeFuMessageContentTypeEnum } from '../tools/constants'
+import ProductItem from './ProductItem.vue'
+import { UserTypeEnum } from '@/utils/constants'
+import { KeFuMessageRespVO } from '@/api/mall/promotion/kefu/message'
+
+defineOptions({ name: 'ImageMessageItem' })
+const props = defineProps<{
+  message: KeFuMessageRespVO
+}>()
+const getMessageContent = computed(() => JSON.parse(props.message.content))
+</script>

+ 194 - 0
src/views/mall/promotion/kefu/components/message/ProductItem.vue

@@ -0,0 +1,194 @@
+<template>
+  <div>
+    <div>
+      <slot name="top"></slot>
+    </div>
+    <div
+      :style="[{ borderRadius: radius + 'px', marginBottom: marginBottom + 'px' }]"
+      class="ss-order-card-warp flex items-stretch justify-between bg-white"
+    >
+      <div class="img-box mr-24px">
+        <el-image :src="img" class="order-img" fit="contain" @click="imagePrediv(img)" />
+      </div>
+      <div
+        :style="[{ width: titleWidth ? titleWidth + 'px' : '' }]"
+        class="box-right flex flex-col justify-between"
+      >
+        <div v-if="title" class="title-text ss-line-2">{{ title }}</div>
+        <div v-if="skuString" class="spec-text mt-8px mb-12px">{{ skuString }}</div>
+        <div class="groupon-box">
+          <slot name="groupon"></slot>
+        </div>
+        <div class="flex">
+          <div class="flex items-center">
+            <div
+              v-if="price && Number(price) > 0"
+              :style="[{ color: priceColor }]"
+              class="price-text flex items-center"
+            >
+              ¥{{ fenToYuan(price) }}
+            </div>
+            <div v-if="num" class="total-text flex items-center">x {{ num }}</div>
+            <slot name="priceSuffix"></slot>
+          </div>
+        </div>
+        <div class="tool-box">
+          <slot name="tool"></slot>
+        </div>
+        <div>
+          <slot name="rightBottom"></slot>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { createImageViewer } from '@/components/ImageViewer'
+import { fenToYuan } from '@/utils'
+
+defineOptions({ name: 'ProductItem' })
+const props = defineProps({
+  img: {
+    type: String,
+    default: 'https://img1.baidu.com/it/u=1601695551,235775011&fm=26&fmt=auto'
+  },
+  title: {
+    type: String,
+    default: ''
+  },
+  titleWidth: {
+    type: Number,
+    default: 0
+  },
+  skuText: {
+    type: [String, Array],
+    default: ''
+  },
+  price: {
+    type: [String, Number],
+    default: ''
+  },
+  priceColor: {
+    type: [String],
+    default: ''
+  },
+  num: {
+    type: [String, Number],
+    default: 0
+  },
+  score: {
+    type: [String, Number],
+    default: ''
+  },
+  radius: {
+    type: [String],
+    default: ''
+  },
+  marginBottom: {
+    type: [String],
+    default: ''
+  }
+})
+const skuString = computed(() => {
+  if (!props.skuText) {
+    return ''
+  }
+  if (typeof props.skuText === 'object') {
+    return props.skuText.join(',')
+  }
+  return props.skuText
+})
+/** 图预览 */
+const imagePrediv = (imgUrl: string) => {
+  createImageViewer({
+    urlList: [imgUrl]
+  })
+}
+</script>
+
+<style lang="scss" scoped>
+.score-img {
+  width: 36px;
+  height: 36px;
+  margin: 0 4px;
+}
+
+.ss-order-card-warp {
+  padding: 20px;
+  background-color: #e2e2e2;
+
+  .img-box {
+    width: 164px;
+    height: 164px;
+    border-radius: 10px;
+    overflow: hidden;
+
+    .order-img {
+      width: 164px;
+      height: 164px;
+    }
+  }
+
+  .box-right {
+    flex: 1;
+    // width: 500px;
+    // height: 164px;
+    position: relative;
+
+    .tool-box {
+      position: absolute;
+      right: 0px;
+      bottom: -10px;
+    }
+  }
+
+  .title-text {
+    font-size: 28px;
+    font-weight: 500;
+    line-height: 40px;
+  }
+
+  .spec-text {
+    font-size: 24px;
+    font-weight: 400;
+    color: #999999;
+    min-width: 0;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    display: -webkit-box;
+    -webkit-line-clamp: 1;
+    -webkit-box-orient: vertical;
+  }
+
+  .price-text {
+    font-size: 24px;
+    font-weight: 500;
+    font-family: OPPOSANS;
+  }
+
+  .total-text {
+    font-size: 24px;
+    font-weight: 400;
+    line-height: 24px;
+    color: #999999;
+    margin-left: 8px;
+  }
+}
+
+.ss-line {
+  min-width: 0;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  -webkit-box-orient: vertical;
+
+  &-1 {
+    -webkit-line-clamp: 1;
+  }
+
+  &-2 {
+    -webkit-line-clamp: 2;
+  }
+}
+</style>

+ 9 - 74
src/views/mall/promotion/kefu/components/message/ProductMessageItem.vue

@@ -10,92 +10,27 @@
             : ''
       ]"
     >
-      <div class="goods flex items-center">
-        <el-image
-          :src="getMessageContent.picUrl"
-          class="image"
-          fit="contain"
-          @click="imagePreview(getMessageContent.picUrl)"
-        />
-        <view class="flex-1">
-          <view class="title ss-line-2">
-            {{ getMessageContent.spuName }}
-          </view>
-          <view v-if="getMessageContent.introduction" class="subtitle ss-line-1">
-            {{ getMessageContent.introduction }}
-          </view>
-          <view class="price mt-8px"> ¥{{ getMessageContent.price }}</view>
-        </view>
-      </div>
+      <ProductItem
+        :img="getMessageContent.picUrl"
+        :price="getMessageContent.price"
+        :skuText="getMessageContent.introduction"
+        :title="getMessageContent.spuName"
+        :titleWidth="400"
+        priceColor="#FF3000"
+      />
     </div>
   </template>
 </template>
 
 <script lang="ts" setup>
 import { KeFuMessageContentTypeEnum } from '../tools/constants'
+import ProductItem from './ProductItem.vue'
 import { UserTypeEnum } from '@/utils/constants'
 import { KeFuMessageRespVO } from '@/api/mall/promotion/kefu/message'
-import { createImageViewer } from '@/components/ImageViewer'
 
 defineOptions({ name: 'ImageMessageItem' })
 const props = defineProps<{
   message: KeFuMessageRespVO
 }>()
 const getMessageContent = computed(() => JSON.parse(props.message.content))
-/** 图预览 */
-const imagePreview = (imgUrl: string) => {
-  createImageViewer({
-    urlList: [imgUrl]
-  })
-}
 </script>
-<style lang="scss" scoped>
-.goods {
-  padding: 20px;
-  border-radius: 12px;
-  background-color: #e1e1e1;
-
-  .ss-line {
-    min-width: 0;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    display: -webkit-box;
-    -webkit-box-orient: vertical;
-
-    &-1 {
-      -webkit-line-clamp: 1;
-    }
-
-    &-2 {
-      -webkit-line-clamp: 2;
-    }
-  }
-
-  .image {
-    width: 116px;
-    height: 116px;
-    flex-shrink: 0;
-    margin-right: 20px;
-  }
-
-  .title {
-    height: 64px;
-    line-height: 32px;
-    font-size: 26px;
-    font-weight: 500;
-    color: #333;
-  }
-
-  .subtitle {
-    font-size: 24px;
-    font-weight: 400;
-    color: #999;
-  }
-
-  .price {
-    font-size: 26px;
-    font-weight: 500;
-    color: #ff3000;
-  }
-}
-</style>