Files
used-car-h5/pages/index/detils.vue
T
2026-01-13 15:10:33 +08:00

394 lines
8.4 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="page">
<!-- 自定义导航(pages.json 里已设置 navigationStyle: custom) -->
<!-- <uni-nav-bar leftText=" " @clickLeft="goBack" leftIcon="back" :fixed="true" :border="false" color="#fff" backgroundColor="#3F435B" :statusBar="true" title="车辆详情"></uni-nav-bar> -->
<view class="content">
<!-- 基础信息卡片 -->
<view class="card">
<view class="title-row">
<text class="name">{{ detail.product_name }}</text>
</view>
<view class="kv">
<!-- <view class="kv-item" @click="copyIfHas('车辆识别码', detail.vin)">
<text class="k">车辆识别码</text>
<text class="v ellipsis">{{ detail.vin }}</text>
<text class="copy" v-if="detail.vin">复制</text>
</view> -->
<view class="kv-item">
<text class="k">车价(¥)</text>
<text class="v">{{ detail.price }}</text>
</view>
<view class="kv-item">
<text class="k">车源地</text>
<text class="v">{{ detail.source_place}}</text>
</view>
<!-- <view class="kv-item">
<text class="k">上牌地</text>
<text class="v">{{ detail.plate_place }}</text>
</view> -->
<view class="kv-item">
<text class="k">上牌时间</text>
<text class="v">{{ detail.plate_time }}</text>
</view>
<view class="kv-item">
<text class="k">排量</text>
<text class="v">{{ detail.displacement }}</text>
</view>
<view class="kv-item">
<text class="k">里程</text>
<text class="v">{{ detail.mileage }}</text>
</view>
<view class="kv-item">
<text class="k">马力</text>
<text class="v">{{ detail.power }}</text>
</view>
<view class="kv-item">
<text class="k">车身颜色</text>
<text class="v">{{ detail.body_color }}</text>
</view>
<view class="kv-item">
<text class="k">创建时间</text>
<text class="v">{{ detail.created_at }}</text>
</view>
</view>
</view>
<!-- 车况介绍 -->
<view class="card">
<view class="section-title">车况介绍</view>
<text class="desc" v-if="detail.condition_desc!=''">{{ detail.condition_desc }}</text>
<view class="noneview" v-else>
<img src="/static/image/none.png" alt="">
</view>
</view>
<view class="hero">
<view class="section-title">产品图</view>
<!-- 有图:九宫格/多行平铺;无图:占位 -->
<view class="img-grid">
<image
v-for="(src, i) in detail.images_pull"
:key="i"
class="grid-img"
:src="src"
mode="aspectFill"
@click="previewImages(i)"
/>
</view>
</view>
<view class="hero">
<view class="section-title">附件</view>
<view v-if="detail.attachment_pull.length>0">
<view v-for="(file, i) in detail.attachment_pull" :key="i" class="fujian" @click="reviewFile(file)">
<p>{{file.name}}</p>
<view>查看</view>
</view>
</view>
<view class="noneview" v-else>
<img src="/static/image/none.png" alt="">
</view>
</view>
</view>
</view>
</template>
<script>
import { request, showToast } from '@/api/apiT.js'
export default {
data() {
return {
id: '',
appid: '',
detail: {},
currentImageIndex: 0
}
},
computed: {
images() {
// 兼容:images 可能是数组、逗号字符串、或后端不同字段
const raw =
this.detail.images_pull ||[]
if (Array.isArray(raw)) {
return raw.filter(Boolean)
}
if (typeof raw === 'string') {
return raw
.split(',')
.map(s => (s || '').trim())
.filter(Boolean)
}
return []
}
},
onLoad(options) {
// 1) 支持通过 id 打开:/pages/index/detils?id=123
this.id = options?.id || ''
// 2) 分享链接里会带 appid,用于未登录时拉起飞书免登
const appid = options?.appid || uni.getStorageSync('fsappid') || ''
if (appid) uni.setStorageSync('fsappid', appid)
// 3) 如果未登录:先去登录页,登录成功后再回到当前详情页
const token = uni.getStorageSync('token')
if (!token) {
const redirect = `/pages/index/detils?id=${this.id}${appid ? `&appid=${encodeURIComponent(appid)}` : ''}`
uni.setStorageSync('post_login_redirect', redirect)
// 使用 reLaunch,避免用户打开分享链接后历史栈混乱
uni.reLaunch({
url: `/pages/login/index?appid=${encodeURIComponent(appid)}&redirect=${encodeURIComponent(redirect)}`
})
return
}
this.getshows()
},
methods: {
//获取详情
getshows(){
let that = this;
request({
url:'common/usedcar/show',
method:'GET',
data:{
id:that.id
}
}).then(res => {
if (res.data.code == 200) {
this.detail = res.data.data
}
})
},
goBack() {
uni.navigateBack({
delta: 1,
fail: () => {
// 某些环境下没有历史栈,兜底回首页
uni.reLaunch({ url: '/pages/index/index' })
}
})
},
previewImages(startIndex) {
if (!this.images || this.images.length === 0) return
this.currentImageIndex = startIndex || 0
uni.previewImage({
current: this.images[this.currentImageIndex],
urls: this.images
})
},
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')
}
},
reviewFile(file){
this.downloadByAnchor(file.src, file.name)
}
}
}
</script>
<style scoped lang="scss">
.page {
min-height: 100vh;
background: #f6f7fb;
}
.content {
padding: 18rpx;
box-sizing: border-box;
}
.hero {
position: relative;
border-radius: 18rpx;
overflow: hidden;
margin-top: 16rpx;
background: #fff;
padding: 18rpx 18rpx;
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.06);
}
.img-grid {
display: flex;
flex-wrap: wrap;
gap: 10rpx;
padding: 10rpx;
box-sizing: border-box;
}
.grid-img {
width: calc((100% - 20rpx) / 3);
height: 220rpx;
border-radius: 14rpx;
background: #f3f4f6;
}
.grid-img-single {
width: 100%;
height: 420rpx;
border-radius: 14rpx;
}
.hero-badges {
position: absolute;
left: 14rpx;
bottom: 14rpx;
display: flex;
gap: 10rpx;
}
.badge {
padding: 10rpx 14rpx;
border-radius: 999rpx;
font-size: 24rpx;
color: #fff;
background: rgba(255, 151, 47, 0.95);
}
.badge-ghost {
background: rgba(0, 0, 0, 0.4);
}
.card {
margin-top: 16rpx;
background: #fff;
border-radius: 18rpx;
padding: 18rpx 18rpx;
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.05);
box-sizing: border-box;
}
.title-row {
display: flex;
align-items: center;
justify-content: space-between;
}
.name {
font-size: 34rpx;
font-weight: 700;
color: #111827;
line-height: 1.2;
}
.sub-row {
margin-top: 10rpx;
display: flex;
justify-content: space-between;
gap: 12rpx;
flex-wrap: wrap;
}
.sub {
font-size: 24rpx;
color: #6b7280;
}
.kv {
display: flex;
flex-direction: column;
}
.kv-item {
padding: 16rpx 0;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1rpx solid #f1f5f9;
}
.kv-item:last-child {
border-bottom: none;
padding-bottom: 0;
}
.k {
width: 180rpx;
font-size: 26rpx;
color: #374151;
flex-shrink: 0;
}
.v {
font-size: 26rpx;
color: #111827;
text-align: right;
flex: 1;
margin-left: 12rpx;
}
.ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.copy {
margin-left: 12rpx;
font-size: 22rpx;
color: #ff972f;
flex-shrink: 0;
}
.section-title {
font-size: 28rpx;
font-weight: 700;
color: #111827;
margin-bottom: 10rpx;
}
.desc {
font-size: 26rpx;
color: #374151;
line-height: 1.7;
white-space: pre-wrap;
}
.footer {
padding: 28rpx 0 40rpx;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
gap: 14rpx;
}
.footer-text {
font-size: 24rpx;
color: #6b7280;
}
.retry {
padding: 14rpx 26rpx;
border-radius: 999rpx;
background: rgba(255, 151, 47, 0.12);
color: #ff972f;
font-size: 24rpx;
}
.fujian{
display: flex;
align-items: center;
justify-content: space-between;
border: 1px solid #ebebeb;
padding: 8px 10px;
border-radius: 4px;
}
.noneview{
text-align: center;
}
</style>