Files
todo-frontend/src/pages/share/order.vue
Agent 7a9c31ca27
All checks were successful
continuous-integration/drone/push Build is passing
fix: 增加总面积列宽度
2026-04-02 12:07:02 +00:00

364 lines
8.0 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="page">
<!-- 自定义导航 -->
<view class="custom-nav">
<text class="nav-title">订单详情</text>
</view>
<!-- 加载中 -->
<view class="loading" v-if="loading">
<text>加载中...</text>
</view>
<!-- 错误 -->
<view class="error" v-else-if="error">
<text class="error-icon"></text>
<text class="error-text">{{ error }}</text>
</view>
<!-- 订单详情 -->
<view class="order-content" v-else-if="order">
<!-- 头部状态 -->
<view class="order-header">
<view class="status-badge" :class="getStatusClass(order.status)">
{{ order.statusText }}
</view>
<text class="order-no">订单号: {{ order.orderNo }}</text>
</view>
<!-- 客户信息 -->
<view class="section">
<view class="section-title">客户信息</view>
<view class="section-content">
<view class="info-row">
<text class="label">客户姓名</text>
<text class="value">{{ order.customerName }}</text>
</view>
<view class="info-row" v-if="order.customerPhone">
<text class="label">联系电话</text>
<text class="value">{{ order.customerPhone }}</text>
</view>
<view class="info-row">
<text class="label">下单时间</text>
<text class="value">{{ formatTime(order.createdAt) }}</text>
</view>
</view>
</view>
<!-- 商品明细 -->
<view class="section">
<view class="section-title">商品明细</view>
<view class="items-list">
<view class="item-row header">
<text class="item-info">商品信息</text>
<text class="item-area">总面积()</text>
<text class="item-qty">数量</text>
<text class="item-price">单价</text>
<text class="item-subtotal">小计</text>
</view>
<view
v-for="(item, index) in order.items"
:key="index"
class="item-row"
>
<text class="item-info"><text class="item-name-text">{{ item.productName }}</text><text class="item-spec-text">{{ item.productSpec ? ' ' + item.productSpec : '' }}</text><text class="item-dims-text">{{ item.length || '-' }}x{{ item.width || '-' }}</text></text>
<text class="item-area">{{ calcArea(item) }}</text>
<text class="item-qty">{{ item.quantity }}</text>
<text class="item-price">¥{{ item.price }}</text>
<text class="item-subtotal">¥{{ (item.price * item.quantity).toFixed(0) }}</text>
</view>
</view>
</view>
<!-- 金额信息 -->
<view class="section amount-section">
<view class="info-row">
<text class="label">原价合计</text>
<text class="value">¥{{ order.totalAmount }}</text>
</view>
<view class="info-row">
<text class="label">优惠金额</text>
<text class="value discount">-¥{{ order.discountAmount }}</text>
</view>
<view class="info-row actual">
<text class="label">实付金额</text>
<text class="value">¥{{ order.actualAmount }}</text>
</view>
<view class="info-row">
<text class="label">支付方式</text>
<text class="value">{{ order.paymentMethod }}</text>
</view>
<view class="info-row" v-if="order.remark">
<text class="label">备注</text>
<text class="value">{{ order.remark }}</text>
</view>
</view>
<!-- 店铺信息 -->
<view class="footer">
<text class="shop-name">建材销售管家</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
loading: true,
error: '',
order: null,
orderNo: '',
customerId: ''
}
},
onLoad(options) {
if (options.orderNo && options.customerId) {
this.orderNo = options.orderNo
this.customerId = options.customerId
this.loadOrder()
} else {
this.error = '参数不完整'
this.loading = false
}
},
methods: {
async loadOrder() {
try {
const res = await uni.request({
url: `https://sales.violin-work.online/api/v1/public/orders/${this.orderNo}?customerId=${this.customerId}`,
method: 'GET'
})
this.loading = false
if (res.data.code === 0) {
this.order = res.data.data
} else {
this.error = res.data.message || '订单不存在'
}
} catch (e) {
this.loading = false
this.error = '加载失败,请检查网络'
}
},
getStatusClass(status) {
const map = {
0: 'status-progress',
1: 'status-success',
2: 'status-cancel',
3: 'status-refunding',
4: 'status-refunded',
9: 'status-returning'
}
return map[status] || ''
},
formatTime(time) {
if (!time) return ''
return time.substring(0, 16).replace('T', ' ')
},
calcArea(item) {
if (item.length && item.width && item.quantity) {
return (item.length * item.width * item.quantity / 1000000).toFixed(4)
}
return '-'
}
}
}
</script>
<style>
.page {
min-height: 100vh;
background: #f5f5f5;
}
.custom-nav {
height: 88rpx;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.nav-title {
font-size: 32rpx;
color: #fff;
font-weight: bold;
}
.loading, .error {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.error-icon {
font-size: 80rpx;
margin-bottom: 20rpx;
}
.error-text {
font-size: 28rpx;
color: #999;
}
.order-content {
padding: 20rpx;
}
.order-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 40rpx 30rpx;
border-radius: 20rpx 20rpx 0 0;
text-align: center;
}
.status-badge {
display: inline-block;
padding: 10rpx 30rpx;
border-radius: 30rpx;
font-size: 26rpx;
color: #fff;
margin-bottom: 16rpx;
}
.status-progress { background: #1890ff; }
.status-success { background: #52c41a; }
.status-cancel { background: #999; }
.status-refunding { background: #fa8c16; }
.status-refunded { background: #ff4d4f; }
.status-returning { background: #722ed1; }
.order-no {
color: rgba(255, 255, 255, 0.8);
font-size: 24rpx;
}
.section {
background: #fff;
margin-bottom: 20rpx;
border-radius: 16rpx;
overflow: hidden;
}
.section-title {
padding: 24rpx 30rpx;
font-size: 28rpx;
font-weight: bold;
color: #333;
border-bottom: 1rpx solid #f0f0f0;
}
.section-content {
padding: 0 30rpx;
}
.info-row {
display: flex;
justify-content: space-between;
padding: 20rpx 0;
border-bottom: 1rpx solid #f8f8f8;
}
.info-row:last-child {
border-bottom: none;
}
.label {
font-size: 26rpx;
color: #666;
}
.value {
font-size: 26rpx;
color: #333;
}
.value.discount {
color: #ff4d4f;
}
.info-row.actual .value {
font-size: 36rpx;
font-weight: bold;
color: #ff4d4f;
}
.items-list {
padding: 0 30rpx;
}
.item-row {
display: flex;
padding: 16rpx 0;
border-bottom: 1rpx solid #f8f8f8;
font-size: 24rpx;
align-items: center;
}
.item-row.header {
background: #f8f9fa;
font-weight: bold;
color: #666;
}
.item-info {
flex: 3;
font-size: 24rpx;
color: #333;
line-height: 1.6;
}
.item-name-text {
color: #333;
font-weight: 500;
}
.item-spec-text {
color: #999;
}
.item-dims-text {
color: #666;
margin-left: 8rpx;
}
.item-area {
flex: 1.5;
text-align: center;
color: #667eea;
font-weight: 500;
}
.item-qty {
flex: 0.8;
text-align: center;
}
.item-price {
flex: 1;
text-align: right;
}
.item-subtotal {
flex: 1;
text-align: right;
color: #ff4d4f;
}
.amount-section {
padding: 20rpx 30rpx;
}
.footer {
text-align: center;
padding: 40rpx;
}
.shop-name {
font-size: 24rpx;
color: #999;
}
</style>