|
|
@@ -0,0 +1,625 @@
|
|
|
+<template>
|
|
|
+ <view class="page-container">
|
|
|
+ <view v-if="loading" class="loading-container">
|
|
|
+ <text>加载中...</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <block v-else-if="detail">
|
|
|
+ <!-- 状态卡片 -->
|
|
|
+ <view class="status-card">
|
|
|
+ <view class="status-header">
|
|
|
+ <text class="status-text">{{ getStatusText() }}</text>
|
|
|
+ <text class="platform-tag">{{ getPlatformName() }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="status-desc" v-if="getStatusDesc()">{{ getStatusDesc() }}</view>
|
|
|
+
|
|
|
+ <!-- 取货/收货码 (部分平台有) -->
|
|
|
+ <view class="codes-row" v-if="detail.fetch_code || detail.pickupPassword || detail.pickup_code">
|
|
|
+ <view class="code-item" v-if="detail.fetch_code || detail.pickupPassword || detail.pickup_code">
|
|
|
+ <text class="label">取货码</text>
|
|
|
+ <text class="value">{{ detail.fetch_code || detail.pickupPassword || detail.pickup_code }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="codes-row" v-if="detail.write_off_code || detail.deliveryPassword || detail.complete_code">
|
|
|
+ <view class="code-item">
|
|
|
+ <text class="label">收货码</text>
|
|
|
+ <text class="value">{{ detail.write_off_code || detail.deliveryPassword || detail.complete_code }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 骑手信息 -->
|
|
|
+ <view class="card" v-if="hasDriverInfo()">
|
|
|
+ <view class="card-title">骑手信息</view>
|
|
|
+ <view class="driver-info">
|
|
|
+ <view class="info-main">
|
|
|
+ <text class="name">{{ getDriverName() || '待接单' }}</text>
|
|
|
+ <text class="phone" v-if="getDriverPhone()" @click="callDriver">{{ getDriverPhone() }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="info-sub" v-if="getDriverExtra()">
|
|
|
+ {{ getDriverExtra() }}
|
|
|
+ </view>
|
|
|
+ <view class="driver-location" v-if="getDriverLocation()">
|
|
|
+ <text class="location-text">{{ getDriverLocation() }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 订单信息 -->
|
|
|
+ <view class="card">
|
|
|
+ <view class="card-title">订单信息</view>
|
|
|
+ <view class="info-row">
|
|
|
+ <text class="label">平台订单号</text>
|
|
|
+ <text class="value copy-btn" @click="copyText(getOrderId())">{{ getOrderId() }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="info-row" v-if="detail.partner_order_code || detail.thirdOrderNo || detail.out_order_id">
|
|
|
+ <text class="label">商家订单号</text>
|
|
|
+ <text class="value">{{ detail.partner_order_code || detail.thirdOrderNo || detail.out_order_id }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="info-row" v-if="getDistance()">
|
|
|
+ <text class="label">配送距离</text>
|
|
|
+ <text class="value">{{ getDistance() }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="info-row" v-if="getWeight()">
|
|
|
+ <text class="label">物品重量</text>
|
|
|
+ <text class="value">{{ getWeight() }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="info-row" v-if="getCreateTime()">
|
|
|
+ <text class="label">下单时间</text>
|
|
|
+ <text class="value">{{ getCreateTime() }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="info-row" v-if="getExpectTime()">
|
|
|
+ <text class="label">预计送达</text>
|
|
|
+ <text class="value">{{ getExpectTime() }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 费用信息 -->
|
|
|
+ <view class="card">
|
|
|
+ <view class="card-title">费用明细</view>
|
|
|
+ <view class="info-row main-price">
|
|
|
+ <text class="label">实际支付</text>
|
|
|
+ <text class="value price">¥{{ getActualPrice() }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="info-row" v-if="getTotalPrice() != getActualPrice()">
|
|
|
+ <text class="label">原价</text>
|
|
|
+ <text class="value">¥{{ getTotalPrice() }}</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 费用列表展开 -->
|
|
|
+ <view class="fee-list" v-if="getFeeList().length > 0">
|
|
|
+ <view class="fee-item" v-for="(item, index) in getFeeList()" :key="index">
|
|
|
+ <text class="fee-name">{{ item.name }}</text>
|
|
|
+ <text class="fee-amount">¥{{ item.amount }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 追踪/日志 -->
|
|
|
+ <view class="card" v-if="getLogs().length > 0">
|
|
|
+ <view class="card-title">订单追踪</view>
|
|
|
+ <view class="log-list">
|
|
|
+ <view class="log-item" v-for="(log, index) in getLogs()" :key="index">
|
|
|
+ <view class="log-time">{{ log.time }}</view>
|
|
|
+ <view class="log-content">
|
|
|
+ <view class="log-status">{{ log.status }}</view>
|
|
|
+ <view class="log-desc" v-if="log.desc">{{ log.desc }}</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ </block>
|
|
|
+ <block v-else>
|
|
|
+ <view class="empty-container">
|
|
|
+ <text>暂无数据</text>
|
|
|
+ </view>
|
|
|
+ </block>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { deliveryOrderDetail } from '@/api/express/delivery';
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'orderDetail',
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ detail: null,
|
|
|
+ loading: true,
|
|
|
+ platform: '', // fengniao, shansong, huolala, shunfeng
|
|
|
+ };
|
|
|
+ },
|
|
|
+ onLoad(options) {
|
|
|
+ console.log('options', options);
|
|
|
+ // 兼容从订单详情页跳转过来的参数
|
|
|
+ // platform: 配送单ID (detailInfo.deliveryId)
|
|
|
+ // orderId: 订单ID (detailInfo.id)
|
|
|
+ if (options.platform) {
|
|
|
+ this.platform = options.platform;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (options.orderId) {
|
|
|
+ this.orderId = options.orderId;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (options.orderSn) {
|
|
|
+ this.orderSn = options.orderSn;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.platform && this.orderId) {
|
|
|
+ this.getData();
|
|
|
+ } else {
|
|
|
+ this.$msg('参数错误');
|
|
|
+ setTimeout(() => {
|
|
|
+ uni.navigateBack();
|
|
|
+ }, 1500);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ getData() {
|
|
|
+ this.loading = true;
|
|
|
+ // 构造请求参数,优先传 id (配送单ID),也传 order_id 供后端备用
|
|
|
+ const params = {};
|
|
|
+ if (this.platform) params.platform = this.platform;
|
|
|
+ if (this.orderId) params.orderId = this.orderId;
|
|
|
+ if (this.orderSn) params.orderSn = this.orderSn;
|
|
|
+ deliveryOrderDetail(params).then(res => {
|
|
|
+ this.loading = false;
|
|
|
+ if (res.code === 1) {
|
|
|
+ // 处理不同平台的嵌套结构
|
|
|
+ // 假设 res.data 是平台返回的原始数据或者包含在 res.data.data 中
|
|
|
+ // 根据 prompt, 某些平台数据在 res.data.data (如 huolala, shansong 可能是 res.data.data)
|
|
|
+ // 我们先尝试判断
|
|
|
+ let raw = res.data;
|
|
|
+
|
|
|
+ // 尝试检测平台
|
|
|
+ this.platform = this.detectPlatform(raw);
|
|
|
+
|
|
|
+ // 如果检测不到,尝试在 .data 中查找 (针对 huolala, shansong 这种结构 {"code":1, "data": {"ret":0, "data": ...}})
|
|
|
+ if (this.platform === 'unknown' && raw.data) {
|
|
|
+ let inner = raw.data;
|
|
|
+ let innerPlatform = this.detectPlatform(inner);
|
|
|
+ if (innerPlatform !== 'unknown') {
|
|
|
+ this.platform = innerPlatform;
|
|
|
+ this.detail = inner;
|
|
|
+ } else if (raw.result) { // 顺丰
|
|
|
+ this.platform = 'shunfeng';
|
|
|
+ this.detail = raw.result;
|
|
|
+ } else if (raw.data && typeof raw.data === 'object') {
|
|
|
+ // 可能是 shansong, huolala 的嵌套
|
|
|
+ this.detail = raw.data; // 此时 detail 可能是 huolala 的 data 字典
|
|
|
+ // 再次检测
|
|
|
+ this.platform = this.detectPlatform(this.detail);
|
|
|
+
|
|
|
+ // 如果还是 unknown,可能需要修正 detail 指向
|
|
|
+ if (this.platform === 'unknown' && raw.data && raw.data.data) {
|
|
|
+ // 针对 huolala: {"ret":0, "data": {...}}
|
|
|
+ this.detail = raw.data.data;
|
|
|
+ this.platform = this.detectPlatform(this.detail);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.detail = raw;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 特殊处理顺丰 (result)
|
|
|
+ if (this.platform === 'unknown' && raw.result) {
|
|
|
+ this.platform = 'shunfeng';
|
|
|
+ this.detail = raw.result;
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('Detected platform:', this.platform);
|
|
|
+ console.log('Detail data:', this.detail);
|
|
|
+ } else {
|
|
|
+ this.$msg(res.msg || '获取详情失败');
|
|
|
+ }
|
|
|
+ }).catch(err => {
|
|
|
+ this.loading = false;
|
|
|
+ console.error(err);
|
|
|
+ this.$msg('请求异常');
|
|
|
+ });
|
|
|
+ },
|
|
|
+ detectPlatform(data) {
|
|
|
+ if (!data) return 'unknown';
|
|
|
+ // 蜂鸟特征
|
|
|
+ if (data.partner_order_code !== undefined && (data.carrier_driver_name !== undefined || data.order_actual_amount_cent !== undefined)) return 'fengniao';
|
|
|
+ // 闪送特征
|
|
|
+ if (data.issOrderNo !== undefined || (data.courier !== undefined && data.orderNo !== undefined)) return 'shansong';
|
|
|
+ // 货拉拉特征
|
|
|
+ if (data.order_display_id !== undefined || data.order_vehicle_id !== undefined) return 'huolala';
|
|
|
+ // 顺丰特征
|
|
|
+ if ((data.order_id && String(data.order_id).startsWith('JS')) || data.rider_name !== undefined || data.sf_order_id !== undefined) return 'shunfeng';
|
|
|
+
|
|
|
+ return 'unknown';
|
|
|
+ },
|
|
|
+ getPlatformName() {
|
|
|
+ const map = {
|
|
|
+ 'fengniao': '蜂鸟跑腿',
|
|
|
+ 'shansong': '闪送',
|
|
|
+ 'huolala': '货拉拉',
|
|
|
+ 'shunfeng': '顺丰同城'
|
|
|
+ };
|
|
|
+ return map[this.platform] || '未知平台';
|
|
|
+ },
|
|
|
+ getStatusText() {
|
|
|
+ if (!this.detail) return '';
|
|
|
+ switch (this.platform) {
|
|
|
+ case 'fengniao':
|
|
|
+ // 0:生成, 1:运单生成, 20:骑手接单, 80:骑手到店, 2:配送中, 3:已完成, 4:取消, 5:异常
|
|
|
+ const fnMap = {0:'待接单', 1:'待接单', 20:'已接单', 80:'已到店', 2:'配送中', 3:'已完成', 4:'已取消', 5:'异常'};
|
|
|
+ return fnMap[this.detail.order_status] || '未知状态';
|
|
|
+ case 'shansong':
|
|
|
+ return this.detail.orderStatusDesc || this.detail.statusDesc || '';
|
|
|
+ case 'huolala':
|
|
|
+ return this.detail.order_status_name || '';
|
|
|
+ case 'shunfeng':
|
|
|
+ // 1:创建, 2:取消, 10:接单, 12:到店, 15:配送中, 17:完成, 31:取消中
|
|
|
+ return this.detail.status_desc || '';
|
|
|
+ default:
|
|
|
+ return '未知';
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getStatusDesc() {
|
|
|
+ if (!this.detail) return '';
|
|
|
+ if (this.platform === 'fengniao') return this.detail.abnormal_desc || '';
|
|
|
+ if (this.platform === 'shansong') return this.detail.subOrderStatusDesc || '';
|
|
|
+ if (this.platform === 'huolala') return this.detail.remark || ''; // 货拉拉似乎没有额外的状态描述
|
|
|
+ return '';
|
|
|
+ },
|
|
|
+ hasDriverInfo() {
|
|
|
+ return this.getDriverName() || this.getDriverPhone();
|
|
|
+ },
|
|
|
+ getDriverName() {
|
|
|
+ if (!this.detail) return '';
|
|
|
+ switch (this.platform) {
|
|
|
+ case 'fengniao': return this.detail.carrier_driver_name;
|
|
|
+ case 'shansong': return this.detail.courier ? this.detail.courier.name : '';
|
|
|
+ case 'huolala': return this.detail.driver_info ? this.detail.driver_info.name : '';
|
|
|
+ case 'shunfeng': return this.detail.rider_name;
|
|
|
+ default: return '';
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getDriverPhone() {
|
|
|
+ if (!this.detail) return '';
|
|
|
+ switch (this.platform) {
|
|
|
+ case 'fengniao': return this.detail.carrier_driver_phone;
|
|
|
+ case 'shansong': return this.detail.courier ? this.detail.courier.mobile : '';
|
|
|
+ case 'huolala': return this.detail.driver_info ? (this.detail.driver_info.driver_phone_no || this.detail.driver_info.phone_no) : '';
|
|
|
+ case 'shunfeng': return this.detail.rider_phone;
|
|
|
+ default: return '';
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getDriverExtra() {
|
|
|
+ if (!this.detail) return '';
|
|
|
+ if (this.platform === 'huolala' && this.detail.driver_info) {
|
|
|
+ return [this.detail.driver_info.physics_vehicle_name, this.detail.driver_info.license_plate].filter(x=>x).join(' | ');
|
|
|
+ }
|
|
|
+ if (this.platform === 'fengniao' && this.detail.temperature) {
|
|
|
+ return this.detail.temperature;
|
|
|
+ }
|
|
|
+ return '';
|
|
|
+ },
|
|
|
+ getDriverLocation() {
|
|
|
+ if (!this.detail) return '';
|
|
|
+ if (this.platform === 'shansong' && this.detail.courier && this.detail.courier.estimateDeliveryTimeTip) {
|
|
|
+ return this.detail.courier.estimateDeliveryTimeTip;
|
|
|
+ }
|
|
|
+ // 经纬度展示略过,直接展示文本信息
|
|
|
+ return '';
|
|
|
+ },
|
|
|
+ callDriver() {
|
|
|
+ const phone = this.getDriverPhone();
|
|
|
+ if (phone) {
|
|
|
+ uni.makePhoneCall({ phoneNumber: phone });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getOrderId() {
|
|
|
+ if (!this.detail) return '';
|
|
|
+ switch (this.platform) {
|
|
|
+ case 'fengniao': return this.detail.partner_order_code || this.detail.order_id; // 优先外部
|
|
|
+ case 'shansong': return this.detail.orderNo || this.detail.issOrderNo;
|
|
|
+ case 'huolala': return this.detail.order_display_id;
|
|
|
+ case 'shunfeng': return this.detail.order_id;
|
|
|
+ default: return '';
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getDistance() {
|
|
|
+ if (!this.detail) return '';
|
|
|
+ if (this.platform === 'fengniao' && this.detail.order_distance) return (this.detail.order_distance / 1000).toFixed(2) + 'km'; // 米
|
|
|
+ if (this.platform === 'shunfeng' && this.detail.delivery_distance_meter) return (this.detail.delivery_distance_meter / 1000).toFixed(2) + 'km';
|
|
|
+ return '';
|
|
|
+ },
|
|
|
+ getWeight() {
|
|
|
+ if (!this.detail) return '';
|
|
|
+ if (this.platform === 'shunfeng' && this.detail.weight_gram) return (this.detail.weight_gram / 1000).toFixed(1) + 'kg';
|
|
|
+ return '';
|
|
|
+ },
|
|
|
+ getCreateTime() {
|
|
|
+ if (!this.detail) return '';
|
|
|
+ if (this.platform === 'huolala' && this.detail.create_time) return this.$util.$formatDate(this.detail.create_time); // unix timestamp seconds
|
|
|
+ if (this.platform === 'shunfeng' && this.detail.push_time) return this.$util.$formatDate(this.detail.push_time);
|
|
|
+ // 其他平台可能需要从日志中获取或未提供明确的创建时间字段
|
|
|
+ return '';
|
|
|
+ },
|
|
|
+ getExpectTime() {
|
|
|
+ if (!this.detail) return '';
|
|
|
+ if (this.platform === 'fengniao' && this.detail.estimate_arrive_time) return this.$util.$formatDate(this.detail.estimate_arrive_time, 'YYYY-MM-DD HH:mm', true); // ms
|
|
|
+ if (this.platform === 'shunfeng' && this.detail.expect_time) return this.$util.$formatDate(this.detail.expect_time); // seconds
|
|
|
+ return '';
|
|
|
+ },
|
|
|
+ getActualPrice() {
|
|
|
+ if (!this.detail) return '0.00';
|
|
|
+ let fen = 0;
|
|
|
+ switch (this.platform) {
|
|
|
+ case 'fengniao': fen = this.detail.order_actual_amount_cent; break;
|
|
|
+ case 'shansong': fen = this.detail.totalFeeAfterSave; break;
|
|
|
+ case 'huolala': fen = this.detail.total_price_fen; break; // 货拉拉 total_price_fen 似乎是总价,need check if unpaid_price_fen is better
|
|
|
+ case 'shunfeng': fen = this.detail.real_pay_money; break;
|
|
|
+ }
|
|
|
+ return (fen / 100).toFixed(2);
|
|
|
+ },
|
|
|
+ getTotalPrice() {
|
|
|
+ if (!this.detail) return '0.00';
|
|
|
+ let fen = 0;
|
|
|
+ switch (this.platform) {
|
|
|
+ case 'fengniao': fen = this.detail.order_total_amount_cent; break;
|
|
|
+ case 'shansong': fen = this.detail.totalAmount; break;
|
|
|
+ case 'huolala': fen = this.detail.total_price_fen; break;
|
|
|
+ case 'shunfeng': fen = this.detail.total_pay_money; break;
|
|
|
+ }
|
|
|
+ return (fen / 100).toFixed(2);
|
|
|
+ },
|
|
|
+ getFeeList() {
|
|
|
+ if (!this.detail) return [];
|
|
|
+ let list = [];
|
|
|
+ if (this.platform === 'fengniao' && this.detail.price_detail) {
|
|
|
+ const p = this.detail.price_detail;
|
|
|
+ // map keys
|
|
|
+ const map = {
|
|
|
+ start_price_cent: '起送价',
|
|
|
+ distance_price_cent: '距离加价',
|
|
|
+ weight_price_cent: '重量加价',
|
|
|
+ time_period_surcharge_cent: '时段加价',
|
|
|
+ tip_amount_cent: '小费'
|
|
|
+ };
|
|
|
+ for (let k in p) {
|
|
|
+ if (map[k] && p[k] > 0) list.push({ name: map[k], amount: (p[k]/100).toFixed(2) });
|
|
|
+ }
|
|
|
+ } else if (this.platform === 'shansong' && this.detail.feeInfoList) {
|
|
|
+ this.detail.feeInfoList.forEach(item => {
|
|
|
+ list.push({ name: item.des, amount: (item.fee/100).toFixed(2) });
|
|
|
+ });
|
|
|
+ } else if (this.platform === 'huolala' && this.detail.price_info) {
|
|
|
+ this.detail.price_info.forEach(item => {
|
|
|
+ list.push({ name: item.bill_type_name, amount: (item.amount_fen/100).toFixed(2) });
|
|
|
+ });
|
|
|
+ } else if (this.platform === 'shunfeng') {
|
|
|
+ if (this.detail.overflow_fee) list.push({ name: '爆单费', amount: (this.detail.overflow_fee/100).toFixed(2) });
|
|
|
+ if (this.detail.coupons_total_fee) list.push({ name: '优惠券', amount: '-' + (this.detail.coupons_total_fee/100).toFixed(2) });
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ },
|
|
|
+ getLogs() {
|
|
|
+ if (!this.detail) return [];
|
|
|
+ let logs = [];
|
|
|
+ if (this.platform === 'fengniao' && this.detail.event_log_details) {
|
|
|
+ logs = this.detail.event_log_details.map(item => ({
|
|
|
+ time: this.$util.$formatDate(item.occur_time, 'YYYY-MM-DD HH:mm', true),
|
|
|
+ status: item.order_status, // 需转义,暂略
|
|
|
+ desc: item.carrier_driver_name ? `骑手: ${item.carrier_driver_name}` : ''
|
|
|
+ }));
|
|
|
+ } else if (this.platform === 'shansong' && this.detail.statusChangeLog) {
|
|
|
+ logs = this.detail.statusChangeLog.map(item => ({
|
|
|
+ time: item.updateTime,
|
|
|
+ status: item.orderStatus // 需转义
|
|
|
+ }));
|
|
|
+ }
|
|
|
+ // 货拉拉和顺丰示例未提供详细日志列表
|
|
|
+ return logs;
|
|
|
+ },
|
|
|
+ copyText(text) {
|
|
|
+ if(!text) return;
|
|
|
+ uni.setClipboardData({
|
|
|
+ data: String(text),
|
|
|
+ success: () => {
|
|
|
+ this.$msg('复制成功');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.page-container {
|
|
|
+ min-height: 100vh;
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ padding: 20upx;
|
|
|
+ padding-bottom: 100upx;
|
|
|
+}
|
|
|
+.loading-container {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ height: 500upx;
|
|
|
+ color: #999;
|
|
|
+}
|
|
|
+.empty-container {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ height: 500upx;
|
|
|
+ color: #999;
|
|
|
+}
|
|
|
+
|
|
|
+.status-card {
|
|
|
+ background: linear-gradient(to right, #3385FF, #5aa0ff);
|
|
|
+ border-radius: 16upx;
|
|
|
+ padding: 40upx 30upx;
|
|
|
+ color: white;
|
|
|
+ margin-bottom: 20upx;
|
|
|
+ box-shadow: 0 4upx 10upx rgba(51, 133, 255, 0.2);
|
|
|
+
|
|
|
+ .status-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 10upx;
|
|
|
+
|
|
|
+ .status-text {
|
|
|
+ font-size: 40upx;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ .platform-tag {
|
|
|
+ font-size: 24upx;
|
|
|
+ background-color: rgba(255,255,255,0.2);
|
|
|
+ padding: 4upx 12upx;
|
|
|
+ border-radius: 8upx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .status-desc {
|
|
|
+ font-size: 28upx;
|
|
|
+ opacity: 0.9;
|
|
|
+ margin-bottom: 20upx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .codes-row {
|
|
|
+ display: flex;
|
|
|
+ margin-top: 30upx;
|
|
|
+ .code-item {
|
|
|
+ margin-right: 40upx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .label {
|
|
|
+ font-size: 24upx;
|
|
|
+ opacity: 0.8;
|
|
|
+ margin-bottom: 4upx;
|
|
|
+ }
|
|
|
+ .value {
|
|
|
+ font-size: 36upx;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.card {
|
|
|
+ background-color: white;
|
|
|
+ border-radius: 16upx;
|
|
|
+ padding: 30upx;
|
|
|
+ margin-bottom: 20upx;
|
|
|
+
|
|
|
+ .card-title {
|
|
|
+ font-size: 30upx;
|
|
|
+ font-weight: bold;
|
|
|
+ margin-bottom: 20upx;
|
|
|
+ color: #333;
|
|
|
+ border-left: 6upx solid #3385FF;
|
|
|
+ padding-left: 14upx;
|
|
|
+ line-height: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ .info-row {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 16upx 0;
|
|
|
+ border-bottom: 1upx solid #f9f9f9;
|
|
|
+ font-size: 28upx;
|
|
|
+
|
|
|
+ &:last-child {
|
|
|
+ border-bottom: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .label {
|
|
|
+ color: #666;
|
|
|
+ }
|
|
|
+ .value {
|
|
|
+ color: #333;
|
|
|
+ &.price {
|
|
|
+ color: #ff5500;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ &.copy-btn {
|
|
|
+ color: #3385FF;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .driver-info {
|
|
|
+ .info-main {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 10upx;
|
|
|
+ .name {
|
|
|
+ font-size: 32upx;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ .phone {
|
|
|
+ color: #3385FF;
|
|
|
+ border: 1upx solid #3385FF;
|
|
|
+ padding: 4upx 16upx;
|
|
|
+ border-radius: 30upx;
|
|
|
+ font-size: 24upx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .info-sub {
|
|
|
+ color: #666;
|
|
|
+ font-size: 26upx;
|
|
|
+ margin-bottom: 10upx;
|
|
|
+ }
|
|
|
+ .driver-location {
|
|
|
+ font-size: 24upx;
|
|
|
+ color: #999;
|
|
|
+ margin-top: 10upx;
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ padding: 10upx;
|
|
|
+ border-radius: 8upx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .fee-list {
|
|
|
+ margin-top: 20upx;
|
|
|
+ padding-top: 20upx;
|
|
|
+ border-top: 1upx solid #eee;
|
|
|
+
|
|
|
+ .fee-item {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ font-size: 26upx;
|
|
|
+ color: #666;
|
|
|
+ margin-bottom: 10upx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .log-list {
|
|
|
+ .log-item {
|
|
|
+ display: flex;
|
|
|
+ margin-bottom: 20upx;
|
|
|
+
|
|
|
+ .log-time {
|
|
|
+ width: 140upx;
|
|
|
+ font-size: 24upx;
|
|
|
+ color: #999;
|
|
|
+ margin-right: 20upx;
|
|
|
+ }
|
|
|
+ .log-content {
|
|
|
+ flex: 1;
|
|
|
+ .log-status {
|
|
|
+ font-size: 28upx;
|
|
|
+ color: #333;
|
|
|
+ margin-bottom: 4upx;
|
|
|
+ }
|
|
|
+ .log-desc {
|
|
|
+ font-size: 24upx;
|
|
|
+ color: #999;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|