<template>
|
<view class="container">
|
<Nav title="上传行程" custom-back="/pages/beReferred/index" />
|
|
<InfoSection :list="infoList" />
|
|
<TabBar :tabs="tabs" :active="activeTab" @switch="switchTab" />
|
|
<view class="form-content">
|
<view class="form-section">
|
<!-- 上传行程:用 v-show 避免切换时销毁/重建表单组件 -->
|
<view v-show="activeTab === 'upload'">
|
<ActionButtons
|
:buttons="actionButtonRows"
|
:selected="selectedAction"
|
:mapList="mapList"
|
@select="selectAction"
|
/>
|
|
<u--form ref="uForm" :rules="rules" :model="form" labelPosition="left">
|
<u-form-item borderBottom label=" " labelWidth="0" prop="address">
|
<view class="form-row" @click="getLocation">
|
<view class="form-label">
|
<view class="label-icon">
|
<u--image :showLoading="true" src="/static/bt.png" width="18" height="18" />
|
</view>
|
<text class="label-text">地址</text>
|
</view>
|
<view class="address-box">
|
<u--text
|
:lines="3"
|
:text="form.address"
|
:placeholder="locationLoading ? '正在获取位置...' : '点击获取当前地址'"
|
/>
|
<view class="location-icon">
|
<u-loading-icon v-if="locationLoading" size="20" color="#409eff" />
|
<u-icon v-else name="map-fill" color="#409eff" size="22" />
|
</view>
|
</view>
|
</view>
|
</u-form-item>
|
|
<u-form-item borderBottom label=" " labelWidth="0" prop="tripTime">
|
<view class="form-row">
|
<view class="form-label">
|
<u--image :showLoading="true" src="/static/bt.png" width="20" height="20" />
|
<text>时间</text>
|
</view>
|
<uni-datetime-picker type="datetime" v-model="form.tripTime" class="flex-1" />
|
</view>
|
</u-form-item>
|
<u-form-item borderBottom label=" " v-if="form.odometer" labelWidth="0" prop="odometer">
|
<view class="form-row">
|
<view class="form-label">
|
<text>仪表里程</text>
|
</view>
|
<view class="form-label">{{form.odometer || 0}} KM</view>
|
</view>
|
</u-form-item>
|
|
<!-- 上传区域 -->
|
<u-form-item v-if="uploadAreas.length" label="凭证" labelWidth="80" :borderBottom="false">
|
<view class="upload-grid">
|
<view
|
v-for="(area, index) in uploadAreas"
|
:key="index"
|
class="upload-item"
|
>
|
<view v-if="!area.imageUrl" class="upload-placeholder" @click="chooseAreaPic(index)">
|
<u-icon name="plus" color="#999" size="32" />
|
<text class="area-name">{{ area.name }}</text>
|
</view>
|
<view v-else class="upload-img-preview">
|
<image :src="area.imageUrl" mode="aspectFill" lazy-load />
|
<view class="delete-btn" @click.stop="deleteAreaPic(index)">
|
<u-icon name="close" color="#fff" size="16" />
|
</view>
|
</view>
|
</view>
|
</view>
|
</u-form-item>
|
</u--form>
|
|
<BottomBar :loading="loading" @submit="submitForm" @history="goThistory" @advance="goToAdvanceList" />
|
</view>
|
|
<!-- 上报垫付:用 v-show 保持表单状态 -->
|
<view v-show="activeTab === 'advance'">
|
<u--form ref="uFormAdvance" :rules="advanceRules" :model="form" labelPosition="left">
|
<u-form-item borderBottom label=" " labelWidth="0" prop="feeType">
|
<view class="form-row">
|
<view class="form-label">
|
<u--image :showLoading="true" src="/static/bt.png" width="20" height="20" />
|
<text>费用类型</text>
|
</view>
|
<uni-data-select v-model="form.feeType" :localdata="range" class="flex-1" />
|
</view>
|
</u-form-item>
|
|
<u-form-item borderBottom label=" " labelWidth="0" prop="currency">
|
<view class="form-row">
|
<view class="form-label">
|
<u--image :showLoading="true" src="/static/bt.png" width="20" height="20" />
|
<text>币制</text>
|
</view>
|
<uni-data-select v-model="form.currency" :localdata="currencyRange" class="flex-1" />
|
</view>
|
</u-form-item>
|
|
<u-form-item borderBottom label=" " labelWidth="0" prop="actualFeeAmount">
|
<view class="form-row">
|
<view class="form-label">
|
<u--image :showLoading="true" src="/static/bt.png" width="20" height="20" />
|
<text>垫付金额</text>
|
</view>
|
<u-number-box
|
v-model="form.actualFeeAmount"
|
class="number-box"
|
:min="0"
|
:step="1"
|
button-size="28"
|
integer
|
/>
|
</view>
|
</u-form-item>
|
|
<u-form-item label="垫付凭证" labelWidth="80" :borderBottom="false">
|
<u-upload
|
:fileList="fileList"
|
name="file"
|
multiple
|
:maxCount="6"
|
:maxSize="50 * 1024 * 1024"
|
@afterRead="afterRead"
|
@delete="deletePic"
|
@oversize="overSize"
|
/>
|
</u-form-item>
|
</u--form>
|
|
<BottomBar :loading="loading" @submit="submitForm" @history="goThistory" @advance="goToAdvanceList" />
|
</view>
|
</view>
|
</view>
|
|
<OdometerPopup
|
:show="showPopup"
|
:form="form"
|
:showCheckCar="form.tripType === '5'"
|
@close="showPopup = false"
|
@submit="handleOdometerSubmit"
|
/>
|
|
<!-- 已提交节点详情弹窗 -->
|
<u-popup :show="show" round="12" mode="center" :closeable="true" @close="show = false">
|
<view v-if="show" class="detail-popup">
|
<view class="detail-header">
|
<view class="detail-icon-wrap">
|
<u-icon name="info-circle-fill" size="22" color="#fa8c16" />
|
</view>
|
<text class="detail-title">该节点已提交过数据,无法重复添加</text>
|
</view>
|
|
<view class="detail-body">
|
<view class="detail-item">
|
<text class="detail-label">提交时间</text>
|
<text class="detail-value">{{ activeActive.createTime || '-' }}</text>
|
</view>
|
<view class="detail-item">
|
<text class="detail-label">提交地址</text>
|
<text class="detail-value">{{ activeActive.address || '-' }}</text>
|
</view>
|
<view class="detail-item detail-item-col">
|
<text class="detail-label">提交凭证</text>
|
<view class="detail-voucher">
|
<image
|
v-for="(img, i) in activeActive.feeVoucherUrl"
|
:key="i"
|
class="voucher-img"
|
:src="img"
|
mode="aspectFill"
|
lazy-load
|
@click="previewImage(img)"
|
/>
|
<text v-if="!activeActive.feeVoucherUrl || !activeActive.feeVoucherUrl.length" class="no-voucher">暂无凭证</text>
|
</view>
|
</view>
|
</view>
|
|
<button class="detail-close-btn" @tap="show = false">我知道了</button>
|
</view>
|
</u-popup>
|
</view>
|
</template>
|
|
<script>
|
import InfoSection from '@/components/InfoSection/index.vue'
|
import TabBar from '@/components/TabBar/index.vue'
|
import ActionButtons from '@/components/ActionButtons/index.vue'
|
import BottomBar from '@/components/BottomBar/index.vue'
|
import OdometerPopup from '@/components/OdometerPopup/index.vue'
|
import { uploadImage } from '@/common/upload'
|
import { getUploadAreas } from '@/common/uploadAreaConfig'
|
import {
|
getcarDispatch,
|
getcarType,
|
carUploadTrip,
|
carUploadFinance,
|
tmsTripList
|
} from '@/common/examine'
|
import amap from '@/common/amap-wx.130.js'
|
import config from '@/config'
|
|
const TABS = Object.freeze([
|
{ key: 'upload', label: '上传行程' },
|
{ key: 'advance', label: '上报垫付' }
|
])
|
|
const INFO_FIELDS = Object.freeze([
|
{ key: 'dispatchNo', label: '调度单号' },
|
{ key: 'licensePlate', label: '车牌号' },
|
{ key: 'transportLine', label: '路线' },
|
{ key: 'customerName', label: '客户' },
|
{ key: 'statusStr', label: '当前状态', status: true, default: '待发车' },
|
{ key: 'latestDeparture', label: '最晚发车时间' },
|
{ key: 'shipperAddress', label: '装货地' },
|
{ key: 'receiverAddress', label: '卸货地' }
|
])
|
|
const SUCCESS_TYPES = Object.freeze(['0', '1', '4', '5', '8', '100'])
|
const ODOMETER_TYPES = Object.freeze(['3', '5', '7'])
|
|
const INITIAL_FORM = Object.freeze({
|
address: '', tripTime: '', odometer: undefined, tripType: '',
|
feeType: '', currency: '', actualFeeAmount: 0,
|
iscc: '1', longitude: '', latitude: ''
|
})
|
|
function formatDateTime() {
|
const d = new Date()
|
const p = n => String(n).padStart(2, '0')
|
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`
|
}
|
|
export default {
|
components: { InfoSection, TabBar, ActionButtons, BottomBar, OdometerPopup },
|
|
data() {
|
return {
|
tabs: TABS,
|
activeTab: 'upload',
|
formData: {},
|
infoList: [],
|
actionButtonRows: [],
|
uploadAreas: [],
|
mapList: {},
|
tmsTripTables: [],
|
newForm: {},
|
selectedAction: '',
|
form: { ...INITIAL_FORM },
|
fileList: [],
|
range: [],
|
currencyRange: [],
|
showPopup: false,
|
show: false,
|
activeActive: {},
|
isHk: false,
|
loading: false,
|
locationLoading: false,
|
rules: Object.freeze({
|
address: [{ required: true, message: '请输入地址', trigger: 'blur' }],
|
tripTime: [{ required: true, message: '请选择时间', trigger: 'change' }]
|
}),
|
advanceRules: Object.freeze({
|
feeType: [{ required: true, message: '请选择费用类型', trigger: 'change' }],
|
currency: [{ required: true, message: '请选择币制', trigger: 'change' }]
|
})
|
}
|
},
|
|
onLoad(options) {
|
this.formData = options
|
this._amapPlugin = new amap.AMapWX({ key: config.mapApiKey })
|
this._locationTimer = null
|
this._needRefresh = false
|
|
if (options.id) {
|
// 并行加载调度信息和字典数据,提升加载速度
|
Promise.all([
|
this.loadDispatchInfo(),
|
this.loadDictData()
|
]).catch(() => {
|
// 错误已在各自方法中处理
|
})
|
this.form.tripTime = formatDateTime()
|
}
|
|
this.getLocation()
|
},
|
|
onShow() {
|
// 检查是否从签署页面提交成功后返回
|
const needRefresh = uni.getStorageSync('needRefreshOperate')
|
if (needRefresh) {
|
uni.removeStorageSync('needRefreshOperate')
|
|
// 刷新字典数据和行程列表
|
this.loadDictData()
|
|
// 重置表单状态
|
this.selectedAction = ''
|
const { address, latitude, longitude } = this.form
|
Object.assign(this.form, { ...INITIAL_FORM }, {
|
tripTime: formatDateTime(),
|
address, latitude, longitude
|
})
|
this.uploadAreas = []
|
}
|
},
|
|
onHide() {
|
this._needRefresh = true
|
},
|
|
onUnload() {
|
if (this._locationTimer) {
|
clearTimeout(this._locationTimer)
|
this._locationTimer = null
|
}
|
},
|
|
methods: {
|
// ========== 数据加载 ==========
|
async loadDispatchInfo() {
|
const fields = INFO_FIELDS.map(f => ({ ...f, value: f.default || '' }))
|
this.infoList = fields
|
try {
|
const res = await getcarDispatch(this.formData.id)
|
this.newForm = res
|
this.infoList = fields.map(f => ({ ...f, value: res[f.key] ?? f.value }))
|
} catch {
|
uni.$u.toast('获取调度信息失败')
|
}
|
},
|
|
async loadDictData() {
|
try {
|
const [feeRes, currencyRes, tripRes, listRes] = await Promise.all([
|
getcarType('fee_type'),
|
getcarType('sys_currency'),
|
getcarType('trip_type'),
|
tmsTripList(this.formData.id)
|
])
|
|
const range = feeRes.map(i => ({ value: i.dictValue, text: i.dictLabel }))
|
const currencyRange = currencyRes.map(i => ({ value: i.dictValue, text: i.dictLabel }))
|
const buttons = tripRes || []
|
const trips = listRes || []
|
|
const grouped = {}
|
for (let i = 0; i < trips.length; i++) {
|
const k = String(trips[i].tripType)
|
;(grouped[k] || (grouped[k] = [])).push(trips[i])
|
}
|
|
for (let i = 0; i < buttons.length; i++) {
|
buttons[i].count = (grouped[buttons[i].dictValue] || []).length
|
}
|
|
this.range = range
|
this.currencyRange = currencyRange
|
this.actionButtonRows = buttons
|
this.mapList = grouped
|
this.tmsTripTables = trips
|
} catch {
|
uni.$u.toast('加载数据失败')
|
}
|
},
|
|
// ========== 定位(防抖 + 超时处理) ==========
|
getLocation() {
|
if (this._locationTimer) clearTimeout(this._locationTimer)
|
this._locationTimer = setTimeout(() => {
|
this.locationLoading = true
|
|
// 设置 10 秒超时
|
const timeout = setTimeout(() => {
|
this.locationLoading = false
|
uni.$u.toast('定位超时,请手动输入地址')
|
}, 10000)
|
|
uni.getLocation({
|
type: 'gcj02',
|
success: (res) => {
|
clearTimeout(timeout)
|
this.form.latitude = res.latitude
|
this.form.longitude = res.longitude
|
this._reverseGeocode(res.latitude, res.longitude)
|
},
|
fail: (err) => {
|
clearTimeout(timeout)
|
this.locationLoading = false
|
console.error('获取位置失败:', err)
|
uni.$u.toast('获取位置失败,请手动输入地址')
|
}
|
})
|
}, 300)
|
},
|
|
_reverseGeocode(lat, lng) {
|
this._amapPlugin.getRegeo({
|
location: `${lng},${lat}`,
|
success: (data) => {
|
this.locationLoading = false
|
const datum = data[0]
|
const province = datum.regeocodeData?.addressComponent?.province
|
this.isHk = province?.includes('香港') || false
|
this.form.address = datum.name
|
},
|
fail: (err) => {
|
this.locationLoading = false
|
console.error('地址解析失败:', err)
|
uni.$u.toast('地址解析失败,请手动输入地址')
|
}
|
})
|
},
|
|
// ========== Tab 切换 ==========
|
switchTab(tab) {
|
if (this.activeTab === tab) return
|
this.activeTab = tab
|
this.selectedAction = ''
|
const { address, latitude, longitude } = this.form
|
Object.assign(this.form, { ...INITIAL_FORM }, {
|
tripTime: formatDateTime(),
|
address, latitude, longitude
|
})
|
this.fileList = []
|
this.uploadAreas = []
|
},
|
|
// ========== 按钮逻辑 ==========
|
getBtnSuccess(row) {
|
return SUCCESS_TYPES.includes(String(row.dictValue)) && row.count > 0
|
},
|
|
checkBtnDisabled(row) {
|
if (row.dictValue == 1) return row.count > 0
|
if (row.dictValue == 0) {
|
if (!this.mapList['1'] || this.mapList['1'].length == 0) return true
|
return row.count > 0
|
}
|
if (!this.mapList['0'] || this.mapList['0'].length == 0) return true
|
if (SUCCESS_TYPES.includes(String(row.dictValue)) && row.count > 0) return true
|
return false
|
},
|
|
selectAction(row) {
|
if (this.getBtnSuccess(row)) {
|
const active = this.mapList[row.dictValue]?.[0] || {}
|
this.activeActive = {
|
...active,
|
feeVoucherUrl: active.voucherUrl
|
? active.voucherUrl.split(',').filter(url => url.trim() !== '')
|
: []
|
}
|
this.show = true
|
return
|
}
|
if (this.checkBtnDisabled(row)) return
|
|
const type = String(row.dictValue)
|
this.selectedAction = type
|
this.form.tripType = type
|
this.uploadAreas = getUploadAreas(type)
|
|
if (type !== '1') {
|
if (ODOMETER_TYPES.includes(type)) {
|
this.form.odometer = this.tmsTripTables[0]?.odometer || undefined
|
this.form.iscc = '1'
|
} else {
|
this.form.odometer = undefined
|
}
|
this.$nextTick(() => { this.showPopup = true })
|
}
|
},
|
|
// ========== 图片上传 ==========
|
async afterRead(e) {
|
try {
|
const res = await uploadImage(e.file[0].url, this.isHk)
|
this.fileList.push(res)
|
} catch {
|
uni.$u.toast('上传失败')
|
}
|
},
|
|
deletePic(e) {
|
this.fileList.splice(e.index, 1)
|
},
|
|
overSize() {
|
uni.$u.toast('图片大小不能超过50MB')
|
},
|
|
chooseAreaPic(index) {
|
uni.chooseImage({
|
count: 1,
|
sizeType: ['compressed'],
|
sourceType: ['album', 'camera'],
|
success: (res) => {
|
uploadImage(res.tempFilePaths[0], this.isHk)
|
.then(r => { this.$set(this.uploadAreas[index], 'imageUrl', r.url) })
|
.catch(() => uni.$u.toast('上传失败'))
|
}
|
})
|
},
|
|
deleteAreaPic(index) {
|
uni.showModal({
|
title: '提示',
|
content: '确定要删除这张图片吗?',
|
success: (res) => {
|
if (res.confirm) this.$set(this.uploadAreas[index], 'imageUrl', '')
|
}
|
})
|
},
|
|
// ========== 表单提交 ==========
|
async submitForm() {
|
if (this.loading) return
|
this.loading = true
|
try {
|
if (this.activeTab === 'upload') {
|
await this.submitTrip()
|
} else {
|
await this.submitAdvance()
|
}
|
} finally {
|
this.loading = false
|
}
|
},
|
|
async submitTrip() {
|
if (!this.form.tripType) return uni.$u.toast('请选择行程类型')
|
|
const empty = this.uploadAreas
|
.filter(a => !a.imageUrl && a.required)
|
.map(a => a.name)
|
.join('、')
|
if (empty) return uni.$u.toast(`未上传:${empty}`)
|
|
await this.$refs.uForm.validate()
|
|
this.form.voucherUrl = this.uploadAreas.filter(a => a.imageUrl).map(a => a.imageUrl).join(',')
|
this.form.dispatchOrderId = this.newForm.dispatchId
|
this.form.driverId = this.newForm.driverId
|
|
if (this.form.tripType === '1') {
|
uni.setStorageSync('signContractForm', this.form)
|
return uni.$u.route('/pages/signContract/index')
|
}
|
|
const res = await carUploadTrip(this.form)
|
if (res === 1) {
|
uni.$u.toast('操作成功')
|
this.selectedAction = ''
|
const { address, latitude, longitude } = this.form
|
Object.assign(this.form, { ...INITIAL_FORM }, {
|
tripTime: formatDateTime(),
|
address, latitude, longitude
|
})
|
this.uploadAreas = []
|
this.loadDictData()
|
}
|
},
|
|
async submitAdvance() {
|
if (this.fileList.length === 0) return uni.$u.toast('请上传凭证')
|
|
await this.$refs.uFormAdvance.validate()
|
|
Object.assign(this.form, {
|
feeVoucherUrl: this.fileList.map(f => f.url).join(','),
|
dispatchOrderId: this.newForm.dispatchId,
|
driverId: this.newForm.driverId,
|
dispatchNo: this.newForm.dispatchNo,
|
licensePlate: this.newForm.licensePlate,
|
transportLine: this.newForm.transportLine,
|
customerName: this.newForm.customerName
|
})
|
|
const cleanForm = {}
|
for (const [k, v] of Object.entries(this.form)) {
|
if (v !== '' && v != null) cleanForm[k] = v
|
}
|
|
const res = await carUploadFinance(cleanForm)
|
if (res === 1) {
|
uni.$u.toast('操作成功')
|
const { address, latitude, longitude } = this.form
|
Object.assign(this.form, { ...INITIAL_FORM }, {
|
tripTime: formatDateTime(),
|
address, latitude, longitude
|
})
|
this.fileList = []
|
}
|
},
|
|
handleOdometerSubmit(data) {
|
console.log(data);
|
Object.assign(this.form, data)
|
this.showPopup = false
|
},
|
|
// ========== 路由跳转 ==========
|
goThistory() {
|
uni.$u.route(`/pages/travelItinerary/index?id=${this.formData.id}&name=行程历史&statusStr=${encodeURIComponent(this.formData.statusStr || '')}&router=/pages/examine/operate`)
|
},
|
|
goToAdvanceList() {
|
uni.$u.route(`/pages/paymentList/index?name=垫付列表&router=/pages/examine/operate&id=${this.formData.id}`)
|
},
|
|
previewImage(url) {
|
uni.previewImage({
|
current: url,
|
urls: this.activeActive.feeVoucherUrl || [url]
|
})
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
.container {
|
display: flex;
|
flex-direction: column;
|
min-height: 100vh;
|
background-color: #f7f7f7;
|
}
|
|
.form-content {
|
flex: 1;
|
padding-bottom: 40rpx;
|
}
|
|
.form-section {
|
padding: 20rpx;
|
background-color: #fff;
|
border-radius: 12rpx;
|
margin: 20rpx;
|
}
|
|
.form-row {
|
display: flex;
|
align-items: flex-start;
|
width: 100%;
|
padding: 10rpx 0;
|
}
|
|
.form-label {
|
display: flex;
|
align-items: center;
|
flex-shrink: 0;
|
margin-right: 20rpx;
|
min-width: 120rpx;
|
padding-top: 16rpx;
|
}
|
|
.label-icon {
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
width: 36rpx;
|
height: 36rpx;
|
margin-right: 8rpx;
|
}
|
|
.label-text {
|
font-size: 28rpx;
|
color: #303133;
|
font-weight: 500;
|
}
|
|
.form-label.required .label-text::after {
|
content: '*';
|
color: #ff4d4f;
|
margin-left: 4rpx;
|
}
|
|
.flex-1 {
|
flex: 1;
|
}
|
|
.address-box {
|
flex: 1;
|
display: flex;
|
align-items: center;
|
background-color: #f5f7fa;
|
border: 2rpx solid #e4e7ed;
|
border-radius: 12rpx;
|
padding: 20rpx 80rpx 20rpx 20rpx;
|
position: relative;
|
}
|
|
.location-icon {
|
position: absolute;
|
top: 50%;
|
right: 0;
|
transform: translateY(-50%);
|
width: 72rpx;
|
height: 72rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
|
.number-box {
|
width: 45%;
|
margin-left: 2%;
|
}
|
|
/* 上传网格 */
|
.upload-grid {
|
display: grid;
|
grid-template-columns: repeat(3, 1fr);
|
gap: 20rpx;
|
}
|
|
.upload-item {
|
width: 100%;
|
height: 200rpx;
|
position: relative;
|
}
|
|
.upload-placeholder {
|
width: 100%;
|
height: 100%;
|
border: 2rpx dashed #ddd;
|
border-radius: 8rpx;
|
display: flex;
|
flex-direction: column;
|
justify-content: center;
|
align-items: center;
|
background-color: #f9f9f9;
|
}
|
|
.area-name {
|
font-size: 24rpx;
|
color: #666;
|
margin-top: 16rpx;
|
}
|
|
.upload-img-preview {
|
width: 100%;
|
height: 100%;
|
border-radius: 8rpx;
|
overflow: hidden;
|
position: relative;
|
}
|
|
.upload-img-preview image {
|
width: 100%;
|
height: 100%;
|
object-fit: cover;
|
}
|
|
.delete-btn {
|
position: absolute;
|
top: -10rpx;
|
right: -10rpx;
|
width: 40rpx;
|
height: 40rpx;
|
border-radius: 50%;
|
background-color: rgba(0, 0, 0, 0.5);
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
z-index: 10;
|
}
|
|
/* 已提交详情弹窗 */
|
.detail-popup {
|
width: 600rpx;
|
padding: 40rpx;
|
}
|
|
.detail-header {
|
display: flex;
|
align-items: flex-start;
|
margin-bottom: 32rpx;
|
padding-bottom: 24rpx;
|
border-bottom: 1rpx solid #f2f3f5;
|
}
|
|
.detail-icon-wrap {
|
flex-shrink: 0;
|
margin-right: 16rpx;
|
margin-top: 4rpx;
|
}
|
|
.detail-title {
|
font-size: 30rpx;
|
font-weight: 600;
|
color: #303133;
|
line-height: 1.5;
|
}
|
|
.detail-body {
|
margin-bottom: 32rpx;
|
}
|
|
.detail-item {
|
display: flex;
|
align-items: flex-start;
|
padding: 16rpx 0;
|
}
|
|
.detail-item + .detail-item {
|
border-top: 1rpx solid #f8f8f8;
|
}
|
|
.detail-item-col {
|
flex-direction: column;
|
}
|
|
.detail-label {
|
font-size: 26rpx;
|
color: #909399;
|
width: 140rpx;
|
flex-shrink: 0;
|
line-height: 1.8;
|
}
|
|
.detail-item-col .detail-label {
|
width: auto;
|
margin-bottom: 16rpx;
|
}
|
|
.detail-value {
|
font-size: 28rpx;
|
color: #303133;
|
flex: 1;
|
line-height: 1.8;
|
word-break: break-all;
|
}
|
|
.detail-voucher {
|
display: flex;
|
flex-wrap: wrap;
|
gap: 16rpx;
|
}
|
|
.voucher-img {
|
width: 160rpx;
|
height: 160rpx;
|
border-radius: 8rpx;
|
border: 1rpx solid #ebeef5;
|
}
|
|
.no-voucher {
|
font-size: 26rpx;
|
color: #c0c4cc;
|
padding: 20rpx 0;
|
}
|
|
.detail-close-btn {
|
width: 100%;
|
height: 80rpx;
|
line-height: 80rpx;
|
font-size: 28rpx;
|
background-color: #f5f7fa;
|
color: #606266;
|
border-radius: 10rpx;
|
border: none;
|
font-weight: 500;
|
}
|
|
.detail-close-btn::after {
|
border: none;
|
}
|
|
.detail-close-btn:active {
|
background-color: #e8eaed;
|
}
|
</style>
|