修改
This commit is contained in:
+189
-135
@@ -20,52 +20,40 @@
|
||||
</view>
|
||||
</view>
|
||||
<view class="list-wrap">
|
||||
<view
|
||||
v-for="(item, idx) in list"
|
||||
:key="item.id "
|
||||
class="car-card"
|
||||
@tap="goDetail(item)"
|
||||
>
|
||||
<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">{{ ym(item.plate_time) }}</text>
|
||||
</view>
|
||||
<view class="kv">
|
||||
<text class="k">里程</text>
|
||||
<text class="v">{{ item.mileage }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<CarCard
|
||||
v-for="item in list"
|
||||
:key="item.id"
|
||||
:item="item"
|
||||
@pdfchange="onSearch"
|
||||
@request-price="onRequestPrice"
|
||||
/>
|
||||
</view>
|
||||
</z-paging>
|
||||
<uni-popup ref="inputDialog" type="dialog">
|
||||
<uni-popup-dialog
|
||||
mode="input"
|
||||
title="请输入价格"
|
||||
:value="priceDialogValue"
|
||||
placeholder="请输入车辆价格"
|
||||
@confirm="dialogInputConfirm"
|
||||
/>
|
||||
</uni-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { request } from '@/api/apiT.js'
|
||||
import CarCard from '@/components/CarCard/CarCard.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CarCard
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
priceDialogItem: null,
|
||||
priceDialogIndex: -1,
|
||||
priceDialogValue: '',
|
||||
keyword: '',
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
@@ -75,11 +63,173 @@
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
|
||||
this.initFeishuShare()
|
||||
// H5:处理分享兜底参数 r(如果路由没命中/经历登录回跳,会先落到首页)
|
||||
// #ifdef H5
|
||||
try {
|
||||
const u = new URL(window.location.href)
|
||||
const r = u.searchParams.get('r')
|
||||
if (r) {
|
||||
const target = decodeURIComponent(r)
|
||||
// 清理地址栏的 r,避免反复跳转
|
||||
u.searchParams.delete('r')
|
||||
window.history.replaceState({}, '', u.toString())
|
||||
// 让首页加载完再跳
|
||||
setTimeout(() => {
|
||||
uni.navigateTo({ url: target })
|
||||
}, 50)
|
||||
}
|
||||
} catch (e) {}
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
ym(dateStr) {
|
||||
return String(dateStr || '').slice(0, 7) // "2026-01"
|
||||
isFeishuEnv() {
|
||||
// 飞书/ Lark 客户端内置浏览器 UA 通常包含 Feishu / Lark
|
||||
try {
|
||||
const ua = (navigator.userAgent || '').toLowerCase()
|
||||
return ua.includes('feishu') || ua.includes('lark')
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
},
|
||||
|
||||
loadFeishuJSSDK() {
|
||||
// 动态加载飞书 H5 JS-SDK(避免你还要改 public/index.html)
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
// 已加载
|
||||
if (typeof window !== 'undefined' && window.h5sdk && window.tt) return resolve(true)
|
||||
// H5 才有 document
|
||||
if (typeof document === 'undefined') return reject(new Error('not in h5 environment'))
|
||||
// 已插入但未 ready
|
||||
const existed = document.querySelector('script[data-feishu-h5sdk="1"]')
|
||||
if (existed) {
|
||||
existed.addEventListener('load', () => resolve(true))
|
||||
existed.addEventListener('error', () => reject(new Error('feishu sdk load error')))
|
||||
return
|
||||
}
|
||||
const s = document.createElement('script')
|
||||
s.async = true
|
||||
s.src = 'https://lf-scm-cn.feishucdn.com/lark/op/h5-js-sdk-1.5.44.js'
|
||||
s.onload = () => resolve(true)
|
||||
s.onerror = () => reject(new Error('feishu sdk load error'))
|
||||
document.head.appendChild(s)
|
||||
} catch (e) {
|
||||
reject(e)
|
||||
}
|
||||
})
|
||||
},
|
||||
getFeishuSignUrl() {
|
||||
// 飞书签名通常要求“去掉 hash 的完整 URL”
|
||||
try {
|
||||
return window.location.href.split('#')[0]
|
||||
} catch (e) {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
initFeishuShare() {
|
||||
try {
|
||||
// 确保在飞书环境
|
||||
// if (!this.isFeishuEnv()) return
|
||||
// 动态加载 SDK
|
||||
this.loadFeishuJSSDK()
|
||||
|
||||
// 这里需要后端提供签名接口:返回 { appId, timestamp, nonceStr, signature }
|
||||
// 你可以按你后端习惯改成:request({ url: 'xxx', ... })
|
||||
// const signUrl = encodeURIComponent(this.getFeishuSignUrl())
|
||||
const signUrl = this.getFeishuSignUrl()
|
||||
|
||||
request({
|
||||
url:'common/auth/feishu/signature',
|
||||
method:'get',
|
||||
data: {url:signUrl,app_id:uni.getStorageSync('fsappid')}
|
||||
}).then(res => {
|
||||
var cfg = res.data.data;
|
||||
window.h5sdk.config({
|
||||
appId: cfg.appId || uni.getStorageSync('fsappid'),
|
||||
timestamp: cfg.timestamp,
|
||||
nonceStr: cfg.nonceStr,
|
||||
signature: cfg.signature,
|
||||
jsApiList: ['shareWebContent','share']
|
||||
})
|
||||
|
||||
window.h5sdk.ready(() => {
|
||||
this._feishuReady = true
|
||||
})
|
||||
window.h5sdk.error((err) => {
|
||||
this._feishuReady = false
|
||||
console.error('Feishu JSSDK error:', err)
|
||||
})
|
||||
})
|
||||
} catch (e) {
|
||||
// 不要阻塞页面,失败就走 H5 的兜底分享
|
||||
console.error('initFeishuShare failed:', e)
|
||||
}
|
||||
},
|
||||
onRequestPrice(payload) {
|
||||
// payload: { item, index }
|
||||
this.priceDialogItem = payload && payload.item ? payload.item : null
|
||||
this.priceDialogIndex = payload && typeof payload.index === 'number' ? payload.index : -1
|
||||
this.priceDialogValue = ''
|
||||
this.$nextTick(() => {
|
||||
this.$refs.inputDialog && this.$refs.inputDialog.open()
|
||||
})
|
||||
},
|
||||
// H5 下载:用 a 标签触发
|
||||
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')
|
||||
}
|
||||
},
|
||||
downloadpdf(item) {
|
||||
request({
|
||||
url: 'common/usedcar/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)
|
||||
}
|
||||
})
|
||||
},
|
||||
dialogInputConfirm(val) {
|
||||
const item = this.priceDialogItem
|
||||
const index = this.priceDialogIndex
|
||||
const price = String(val || '').trim()
|
||||
|
||||
if (!item) return
|
||||
if (!price) {
|
||||
uni.showToast({ title: '请输入价格', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (isNaN(price) || Number(price) <= 0) {
|
||||
uni.showToast({ title: '请输入有效的价格', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
request({
|
||||
url: 'common/usedcar/produce/pdf',
|
||||
method: 'get',
|
||||
data: { id: item.id, price }
|
||||
}).then(res => {
|
||||
if (res.data.code == 200) {
|
||||
// 通知刷新列表(你原来就是靠这个事件刷新)
|
||||
this.onSearch()
|
||||
|
||||
this.downloadpdf(item)
|
||||
} else {
|
||||
uni.showToast({ title: res.data.msg || '生成失败', icon: 'none' })
|
||||
}
|
||||
})
|
||||
},
|
||||
onKeywordChange(val) {
|
||||
// val 是输入值(uView 通常会传)
|
||||
@@ -116,23 +266,6 @@
|
||||
uni.stopPullDownRefresh();
|
||||
//
|
||||
})
|
||||
},
|
||||
goDetail(item) {
|
||||
// 你后续详情页如果要接 id,这里按后端字段改一下即可
|
||||
const id = item.id
|
||||
uni.navigateTo({
|
||||
url: `/pages/index/detils?id=${id}`
|
||||
})
|
||||
},
|
||||
formatMileage(v) {
|
||||
if (v === '-' || v === undefined || v === null || String(v).trim() === '') return '-'
|
||||
const n = Number(v)
|
||||
if (isNaN(n)) return String(v)
|
||||
// < 10000:直接显示;>= 10000:转万
|
||||
if (n >= 10000) {
|
||||
return `${(n / 10000).toFixed(1)}万 km`
|
||||
}
|
||||
return `${Math.round(n)} km`
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,7 +288,7 @@
|
||||
|
||||
.head-search {
|
||||
background: rgba(255, 255, 255, 1);
|
||||
border-radius: 18rpx;
|
||||
border-radius: 9px 9px 0px 0px;
|
||||
padding: 20rpx 10px;
|
||||
box-shadow: 0 10rpx 28rpx rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
@@ -164,85 +297,6 @@
|
||||
padding: 18rpx 24rpx 40rpx;
|
||||
}
|
||||
|
||||
.car-card {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
padding: 18rpx;
|
||||
border-radius: 18rpx;
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.06);
|
||||
margin-bottom: 18rpx;
|
||||
}
|
||||
|
||||
.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: 420rpx;
|
||||
}
|
||||
|
||||
.tag {
|
||||
font-size: 22rpx;
|
||||
padding: 6rpx 12rpx;
|
||||
border-radius: 999rpx;
|
||||
background: rgba(255, 151, 47, 0.14);
|
||||
color: #b45309;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.row2,
|
||||
.row3 {
|
||||
justify-content: space-between;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.loadmore {
|
||||
padding: 18rpx 0 6rpx;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user