Files
smt-used-car-h5/components/CarCardPro/CarCardPro.vue
T
2026-03-11 11:45:30 +08:00

511 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="car-card-pro">
<view class="heard">
<view class="heard-left" @click="handleCardTap">
<text class="code-text">编号:{{item.code?item.code:'~'}}</text>
<view class="status-tag" :class="'status-' + item.status">
<text class="status-text">{{ getStatusText(item.status) }}</text>
</view>
</view>
<view v-if="ismy">
<u-icon @click="editfn(item)" name="edit-pen-fill" size="25" />
</view>
</view>
<view class="car-card" @click="handleCardTap">
<image class="thumb" :src="item.images_pull[0]" mode="aspectFill" />
<view class="info">
<view class="row row1">
<text class="name u-line-1">{{ item.product_name }}</text>
</view>
<view class="row row2">
<view class="kv">
<text class="k">车源地</text>
<text class="v u-line-1">{{ item.source_place }}</text>
</view>
<view class="kv">
<text class="k">车身颜色</text>
<text class="v u-line-1">{{ item.body_color }}</text>
</view>
</view>
<view class="row row3">
<view class="kv">
<text class="k">上牌时间</text>
<text class="v">{{ formatPlateTime(item.plate_time) }}</text>
</view>
<view class="kv">
<text class="k">里程</text>
<text class="v">{{ item.mileage }} <text v-if="item.mileage">Km</text> </text>
</view>
</view>
</view>
</view>
<!-- 操作区 -->
<view class="card-actions">
<view class="actions-lift" @click="handleCardTap">
<text class="">创建时间:</text>
<text class="">{{ item.created_at }}</text>
</view>
<!-- <view class="right-btn">
<view class="action-btn" @tap.stop="handleToggleSave">
<u-icon name="download" size="18" />
</view>
<view class="action-btn" @tap.stop="handleShare">
<u-icon name="share" size="18" />
</view>
<view class="action-btn" @tap.stop="handleSet(item)" v-if="item.status==1">
<u-icon name="setting" size="18" />
</view>
</view> -->
</view>
</view>
</template>
<script>
import { request } from '@/api/apiT.js'
export default {
name: 'CarCardPro',
props: {
item: {
type: Object,
required: true
},
ismy: {
default: false,
type: Boolean
},
index: {
type: Number,
default: -1
}
},
computed: {
// 获取状态文本
getStatusText() {
return (status) => {
const statusMap = {
0: '待审核',
1: '审核通过',
2: '审核拒绝'
}
return statusMap[status] || '未知'
}
},
// 计算视频数量
videoCount() {
if (!this.item.intro_video) return 0
if (Array.isArray(this.item.intro_video)) {
return this.item.intro_video.filter(Boolean).length
}
if (typeof this.item.intro_video === 'string') {
return this.item.intro_video.split(',').filter(s => s.trim()).length
}
return 0
},
// 计算FAQ数量
faqCount() {
if (!this.item.faqs) return 0
if (Array.isArray(this.item.faqs)) {
return this.item.faqs.filter(f => f.question && f.answer).length
}
return 0
}
},
methods: {
// 跳转到编辑页面(供应商发布专用编辑页)
editfn(item) {
const id = item.id
uni.navigateTo({
url: `/pages/index/publisheditPro?id=${id}`
})
},
formatPlateTime(dateStr) {
return String(dateStr || '').slice(0, 7)
},
pdfchanges() {
this.$emit('pdfchange')
},
// 标记已售出
handleSet(item) {
const that = this
uni.showModal({
title: '提示',
content: '确认标记已售出?',
success: res => {
if (res.confirm) {
request({
url: 'common/usedcardetail/update/status',
method: 'post',
data: { id: item.id, status: 2 }
}).then(res => {
uni.showToast({
title: res.data.message,
icon: 'none'
})
setTimeout(() => {
that.$emit('restchange')
}, 1000)
})
}
}
})
},
// 跳转到专业详情页
handleCardTap() {
if (this.item && this.item.id) {
const id = this.item.id
uni.navigateTo({
url: `/pages/index/detilsPro?id=${id}`
})
} else {
console.error('CarCardPro: item or item.id is missing', this.item)
}
},
// H5 下载
downloadByAnchor(url, filename) {
try {
const a = document.createElement('a')
a.href = url
a.download = filename || ''
a.target = '_blank'
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
} catch (e) {
if (typeof window !== 'undefined') window.open(url, '_blank')
}
},
// 下载PDF
downloadpdf(item) {
request({
url: 'common/usedcardetail/pdf',
method: 'get',
data: { id: item.id }
}).then(res => {
if (res.data.code == 200) {
this.downloadByAnchor(res.data.data.pdf_url, res.data.data.file_name)
}
})
},
// 请求生成PDF
handleToggleSave() {
const item = this.item
this.$emit('request-price', { item, index: this.index })
},
// 生成分享链接
buildShareLink(id) {
const path = `pages/index/detilsPro?id=${id}&appid=${uni.getStorageSync('fsappid')}`
// #ifdef H5
try {
const origin = window.location.origin
return `${origin}/${path}`
} catch (e) {
return path
}
// #endif
return path
},
// 判断是否在飞书环境
isFeishuEnv() {
try {
const ua = (navigator.userAgent || '').toLowerCase()
return ua.includes('feishu') || ua.includes('lark')
} catch (e) {
return false
}
},
// 飞书分享
feishuShare(payload) {
try {
if (!this.isFeishuEnv()) return false
if (!window || !window.tt || !window.h5sdk) return false
window.h5sdk.ready(() => {
if (typeof window.tt.shareWebContent === 'function') {
window.tt.shareWebContent({
title: payload.title,
content: payload.desc,
url: payload.link,
imageUrl: payload.imageUrl,
success: () => {
uni.showToast({ title: '已唤起飞书分享', icon: 'none' })
},
fail: (err) => {
console.error('feishu shareWebContent fail:', err)
uni.showToast({ title: '分享失败,可复制链接', icon: 'none' })
}
})
} else if (typeof window.tt.share === 'function') {
window.tt.share({
title: payload.title,
desc: payload.desc,
link: payload.link,
imageUrl: payload.imageUrl,
success: () => {
uni.showToast({ title: '已唤起飞书分享', icon: 'none' })
},
fail: (err) => {
console.error('feishu share fail:', err)
uni.showToast({ title: '分享失败,可复制链接', icon: 'none' })
}
})
}
})
return true
} catch (e) {
return false
}
},
// 分享处理
handleShare() {
const item = this.item
const title = item.product_name || '车辆详情'
const link = this.buildShareLink(item.id)
const imageUrl = (item.images_pull && item.images_pull[0]) ? item.images_pull[0] : ''
// #ifdef MP-WEIXIN
uni.showShareMenu({ withShareTicket: true })
uni.showToast({ title: '请使用右上角分享', icon: 'none' })
// #endif
// #ifdef H5
const ok = this.feishuShare({
title,
desc: title,
link,
imageUrl
})
if (ok) return
if (typeof navigator !== 'undefined' && navigator.share) {
navigator.share({ title, text: title, url: link }).catch(() => {})
return
}
// #endif
uni.showActionSheet({
itemList: ['复制链接', '复制标题'],
success: (res) => {
if (res.tapIndex === 0) {
uni.setClipboardData({ data: link })
} else {
uni.setClipboardData({ data: title })
}
}
})
}
}
}
</script>
<style lang="scss" scoped>
.heard {
padding: 5px 10px;
color: #666;
font-size: 12px;
display: flex;
align-items: center;
justify-content: space-between;
}
.heard-left {
display: flex;
align-items: center;
gap: 10rpx;
flex: 1;
min-width: 0;
}
.code-text {
flex-shrink: 0;
}
.status-tag {
padding: 4rpx 12rpx;
border-radius: 8rpx;
font-size: 20rpx;
flex-shrink: 0;
&.status-0 {
background: #FFF7E6;
border: 1px solid #FFD591;
.status-text {
color: #FA8C16;
}
}
&.status-1 {
background: #F6FFED;
border: 1px solid #B7EB8F;
.status-text {
color: #52C41A;
}
}
&.status-2 {
background: #FFF2F0;
border: 1px solid #FFCCC7;
.status-text {
color: #F5222D;
}
}
}
.status-text {
font-size: 20rpx;
font-weight: 500;
}
.car-card-pro {
padding-bottom: 6rpx;
border-radius: 18rpx;
background: linear-gradient(135deg, #fff 0%, #f8f9ff 100%);
// box-shadow: 0 10rpx 30rpx rgba(46, 108, 246, 0.12);
margin-bottom: 18rpx;
cursor: pointer;
border: 1px solid rgba(46, 108, 246, 0.1);
}
.car-card {
position: relative;
display: flex;
align-items: stretch;
padding: 18rpx;
}
.card-actions {
padding: 18rpx;
display: flex;
align-items: center;
justify-content: space-between;
gap: 14rpx;
border-top: 1px solid #e1e1e1;
}
.actions-lift {
font-size: 12px;
}
.right-btn {
display: flex;
gap: 14rpx;
}
.action-btn {
width: 50rpx;
height: 50rpx;
border-radius: 999rpx;
background: rgba(255, 255, 255, 0.92);
box-shadow: 0 8rpx 18rpx rgba(0, 0, 0, 0.12);
display: flex;
align-items: center;
justify-content: center;
}
.action-btn:active {
transform: scale(0.96);
}
.thumb {
width: 190rpx;
height: 140rpx;
border-radius: 14rpx;
background: #eef2f7;
flex-shrink: 0;
}
.info {
flex: 1;
margin-left: 18rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.row {
display: flex;
align-items: center;
}
.row1 {
justify-content: space-between;
margin-bottom: 10rpx;
}
.name {
font-size: 30rpx;
font-weight: 700;
color: #111827;
max-width: 280rpx;
}
.row2,
.row3 {
justify-content: space-between;
gap: 16rpx;
}
.row3 {
margin-bottom: 8rpx;
}
// 特性标签行
.row4 {
gap: 12rpx;
margin-top: 6rpx;
}
.feature-tag {
display: flex;
align-items: center;
gap: 6rpx;
padding: 6rpx 12rpx;
border-radius: 12rpx;
background: rgba(46, 108, 246, 0.08);
.tag-text {
font-size: 20rpx;
color: #2E6CF6;
}
&:nth-child(2) {
background: rgba(255, 151, 47, 0.08);
.tag-text {
color: #FF972F;
}
}
}
.tag-text-empty {
font-size: 20rpx;
color: #999;
font-style: italic;
}
.kv {
flex: 1;
min-width: 0;
display: flex;
align-items: baseline;
}
.k {
font-size: 22rpx;
color: #6b7280;
margin-right: 10rpx;
flex-shrink: 0;
}
.v {
font-size: 24rpx;
color: #374151;
font-weight: 600;
min-width: 0;
}
</style>