【优化】mall 客服商品消息

pull/476/head
puhui999 2024-07-09 17:00:58 +08:00
parent 9dfb869a4b
commit ebc995ac4c
3 changed files with 239 additions and 74 deletions

View File

@ -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>

View File

@ -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>

View File

@ -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>