更新项目配置和添加小程序模块
- 修改 ArticleController.java - 更新 application.yml 配置 - 更新 frontend/.env.production 环境配置 - 添加 single_uniapp22miao 小程序模块 - 添加 logs 目录
This commit is contained in:
862
single_uniapp22miao/pages/integral/order-detail.vue
Normal file
862
single_uniapp22miao/pages/integral/order-detail.vue
Normal file
@@ -0,0 +1,862 @@
|
||||
<template>
|
||||
<view class="order-detail-page">
|
||||
<!-- 橙色头部 -->
|
||||
<view class="header-section">
|
||||
<view class="header-content">
|
||||
<text class="header-icon" @click="goBack">‹</text>
|
||||
<text class="header-title">订单详情</text>
|
||||
<view class="header-placeholder"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<scroll-view class="content" scroll-y>
|
||||
<!-- 状态和进度卡片 -->
|
||||
<view class="card-section status-card">
|
||||
<!-- 状态头部 -->
|
||||
<view class="status-header">
|
||||
<text class="status-text">{{ orderInfo.status_text }}</text>
|
||||
<text class="order-no-text">订单号: {{ orderInfo.order_no }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 进度条 -->
|
||||
<view class="progress-bar">
|
||||
<view
|
||||
v-for="(step, index) in progressSteps"
|
||||
:key="index"
|
||||
class="progress-step"
|
||||
:class="{ 'active': index <= currentProgressIndex, 'current': index === currentProgressIndex }"
|
||||
>
|
||||
<view class="step-icon-wrap">
|
||||
<view class="step-icon">
|
||||
<text class="icon-text">{{ getStepIcon(index) }}</text>
|
||||
</view>
|
||||
<view v-if="index < progressSteps.length - 1" class="step-line"></view>
|
||||
</view>
|
||||
<text class="step-text">{{ step.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 收货信息 -->
|
||||
<view class="card-section address-card">
|
||||
<view class="address-icon">
|
||||
<text class="icon-location">📍</text>
|
||||
</view>
|
||||
<view class="address-content">
|
||||
<view class="address-row">
|
||||
<text class="receiver-name">{{ orderInfo.receiver_name }}</text>
|
||||
<text class="receiver-phone">{{ orderInfo.receiver_phone }}</text>
|
||||
</view>
|
||||
<text class="address-text">{{ orderInfo.receiver_address }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品信息 -->
|
||||
<view class="card-section goods-card">
|
||||
<view class="card-header">
|
||||
<text class="card-title">商品信息</text>
|
||||
</view>
|
||||
|
||||
<!-- 商品列表 -->
|
||||
<view class="goods-list">
|
||||
<view
|
||||
v-for="(goods, index) in orderInfo.orderInfoList"
|
||||
:key="index"
|
||||
class="goods-item"
|
||||
>
|
||||
<text class="goods-name">{{ goods.storeName || goods.productName }}</text>
|
||||
<view class="goods-price-row">
|
||||
<text class="goods-price">{{ formatPoints(goods.integral || goods.vipPrice || goods.price) }}积分</text>
|
||||
<text class="goods-qty">x{{ goods.cartNum }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 无商品时显示默认 -->
|
||||
<view v-if="!orderInfo.orderInfoList || orderInfo.orderInfoList.length === 0" class="goods-item">
|
||||
<text class="goods-name">{{ orderInfo.goods_name }}</text>
|
||||
<view class="goods-price-row">
|
||||
<text class="goods-price">{{ formatPoints(orderInfo.points) }}积分</text>
|
||||
<text class="goods-qty">x{{ orderInfo.quantity }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 汇总信息 -->
|
||||
<view class="goods-summary">
|
||||
<view class="summary-row">
|
||||
<text class="summary-label">商品数量</text>
|
||||
<text class="summary-value">{{ orderInfo.quantity }}件</text>
|
||||
</view>
|
||||
<view class="summary-row">
|
||||
<text class="summary-label">总计</text>
|
||||
<text class="summary-total">{{ formatPoints(orderInfo.points) }}积分</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 订单信息 -->
|
||||
<view class="card-section order-info-card">
|
||||
<view class="card-header">
|
||||
<text class="card-title">订单信息</text>
|
||||
</view>
|
||||
<view class="info-content">
|
||||
<view class="info-row">
|
||||
<text class="info-label">订单编号</text>
|
||||
<text class="info-value" @click="copyText(orderInfo.order_no)">{{ orderInfo.order_no }}</text>
|
||||
</view>
|
||||
<view class="info-row">
|
||||
<text class="info-label">下单时间</text>
|
||||
<text class="info-value">{{ orderInfo.created_at }}</text>
|
||||
</view>
|
||||
<view class="info-row">
|
||||
<text class="info-label">订单状态</text>
|
||||
<text class="info-value status-value">{{ orderInfo.status_text }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<view v-if="showActions" class="bottom-actions">
|
||||
<!-- 待兑换(未付款): 取消订单、立即支付 -->
|
||||
<template v-if="!orderInfo.paid">
|
||||
<button class="action-btn cancel-btn" @click="cancelOrder">取消订单</button>
|
||||
<button class="action-btn primary-btn" @click="goPay">立即兑换</button>
|
||||
</template>
|
||||
<!-- 待收货: 确认收货 -->
|
||||
<template v-else-if="orderInfo.paid && orderInfo.status === 1">
|
||||
<button class="action-btn primary-btn" @click="confirmReceipt">确认收货</button>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getOrderDetail, orderCancel, orderTake } from '@/api/order.js';
|
||||
import { mapGetters } from 'vuex';
|
||||
import { toLogin } from '@/libs/login.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
orderId: '',
|
||||
orderInfo: {
|
||||
id: '',
|
||||
order_no: '',
|
||||
goods_id: '',
|
||||
goods_name: '',
|
||||
goods_image: '',
|
||||
quantity: 1,
|
||||
points: 0,
|
||||
status: 1,
|
||||
paid: true,
|
||||
status_text: '',
|
||||
express_company: '',
|
||||
express_no: '',
|
||||
receiver_name: '',
|
||||
receiver_phone: '',
|
||||
receiver_address: '',
|
||||
created_at: '',
|
||||
pay_at: '',
|
||||
ship_at: '',
|
||||
finish_at: '',
|
||||
orderInfoList: []
|
||||
},
|
||||
progressSteps: [
|
||||
{ name: '待兑换', status: 0 },
|
||||
{ name: '待发货', status: 1 },
|
||||
{ name: '待收货', status: 2 },
|
||||
{ name: '已完成', status: 3 }
|
||||
],
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapGetters(['isLogin']),
|
||||
|
||||
showActions() {
|
||||
// 待兑换(未付款)显示取消按钮,待收货显示确认收货按钮
|
||||
return (!this.orderInfo.paid) || (this.orderInfo.paid && this.orderInfo.status === 1)
|
||||
},
|
||||
|
||||
// 计算总积分
|
||||
totalPoints() {
|
||||
return this.orderInfo.points || 0;
|
||||
},
|
||||
|
||||
// 当前进度索引
|
||||
currentProgressIndex() {
|
||||
if (!this.orderInfo.paid) return 0; // 待兑换
|
||||
// status: 0-待发货 1-待收货 2-待评价 3-已完成
|
||||
if (this.orderInfo.status === 0) return 1; // 待发货
|
||||
if (this.orderInfo.status === 1) return 2; // 待收货
|
||||
if (this.orderInfo.status >= 2) return 3; // 已完成
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
if (options.id) {
|
||||
this.orderId = options.id
|
||||
this.loadOrderDetail()
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 返回上一页
|
||||
goBack() {
|
||||
uni.navigateBack()
|
||||
},
|
||||
|
||||
// 格式化积分数字(添加千分位逗号)
|
||||
formatPoints(points) {
|
||||
if (!points && points !== 0) return '0'
|
||||
return points.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
||||
},
|
||||
|
||||
// 获取步骤图标
|
||||
getStepIcon(index) {
|
||||
const icons = ['⏱', '📦', '🚚', '✓'];
|
||||
return icons[index] || '○';
|
||||
},
|
||||
|
||||
// 加载订单详情
|
||||
async loadOrderDetail() {
|
||||
if (this.loading) return
|
||||
|
||||
// 检查登录状态
|
||||
if (!this.isLogin) {
|
||||
toLogin();
|
||||
return;
|
||||
}
|
||||
|
||||
this.loading = true
|
||||
uni.showLoading({ title: '加载中...' })
|
||||
|
||||
try {
|
||||
const res = await getOrderDetail(this.orderId);
|
||||
|
||||
if (res.data) {
|
||||
const order = res.data;
|
||||
const orderInfoList = order.orderInfoList || [];
|
||||
|
||||
// 获取第一个商品信息
|
||||
let goodsName = '商品名称';
|
||||
let goodsImage = '/static/images/default-goods.png';
|
||||
let totalNum = order.totalNum || 1;
|
||||
|
||||
// 计算总积分:优先使用payIntegral/useIntegral,否则从商品列表计算
|
||||
let totalPoints = 0;
|
||||
|
||||
// 优先使用订单级别的积分字段
|
||||
if (order.payIntegral !== undefined && order.payIntegral !== null) {
|
||||
totalPoints = parseFloat(order.payIntegral) || 0;
|
||||
} else if (order.useIntegral !== undefined && order.useIntegral !== null) {
|
||||
totalPoints = parseFloat(order.useIntegral) || 0;
|
||||
} else if (order.integral !== undefined && order.integral !== null) {
|
||||
totalPoints = parseFloat(order.integral) || 0;
|
||||
} else {
|
||||
// 从商品列表计算总积分
|
||||
totalPoints = orderInfoList.reduce((sum, item) => {
|
||||
// 优先使用integral字段,否则使用vipPrice或price
|
||||
const itemPoints = parseFloat(item.integral) || parseFloat(item.vipPrice) || parseFloat(item.price) || 0;
|
||||
const quantity = parseInt(item.cartNum) || 1;
|
||||
return sum + (itemPoints * quantity);
|
||||
}, 0);
|
||||
|
||||
// 如果计算结果为0,尝试使用payPrice或totalPrice
|
||||
if (totalPoints === 0) {
|
||||
totalPoints = parseFloat(order.payPrice) || parseFloat(order.totalPrice) || 0;
|
||||
}
|
||||
}
|
||||
|
||||
console.log('订单详情积分计算:', {
|
||||
orderId: order.orderId,
|
||||
payIntegral: order.payIntegral,
|
||||
useIntegral: order.useIntegral,
|
||||
integral: order.integral,
|
||||
payPrice: order.payPrice,
|
||||
totalPrice: order.totalPrice,
|
||||
calculatedPoints: totalPoints,
|
||||
orderInfoList: orderInfoList.map(item => ({
|
||||
name: item.storeName,
|
||||
integral: item.integral,
|
||||
vipPrice: item.vipPrice,
|
||||
price: item.price,
|
||||
cartNum: item.cartNum
|
||||
}))
|
||||
});
|
||||
|
||||
if (orderInfoList.length > 0) {
|
||||
const firstGoods = orderInfoList[0];
|
||||
goodsName = firstGoods.storeName || firstGoods.productName || goodsName;
|
||||
goodsImage = firstGoods.image || goodsImage;
|
||||
}
|
||||
|
||||
// 格式化订单数据
|
||||
this.orderInfo = {
|
||||
id: order.id,
|
||||
order_no: order.orderId || order.orderNo || '',
|
||||
goods_id: orderInfoList.length > 0 ? orderInfoList[0].productId : '',
|
||||
goods_name: goodsName,
|
||||
goods_image: goodsImage,
|
||||
quantity: totalNum,
|
||||
points: totalPoints,
|
||||
status: order.status,
|
||||
paid: order.paid,
|
||||
status_text: order.orderStatus || this.getStatusText(order.status, order.paid),
|
||||
express_company: order.deliveryName || '',
|
||||
express_no: order.deliveryId || '',
|
||||
receiver_name: order.realName || '',
|
||||
receiver_phone: order.userPhone || '',
|
||||
receiver_address: order.userAddress || '',
|
||||
created_at: order.createTime || '',
|
||||
pay_at: order.payTime || '',
|
||||
ship_at: order.deliveryTime || '',
|
||||
finish_at: order.finishTime || '',
|
||||
orderInfoList: orderInfoList
|
||||
};
|
||||
} else {
|
||||
throw new Error(res.msg || '加载失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载订单详情失败:', error)
|
||||
uni.showToast({
|
||||
title: error.msg || error.message || '加载失败',
|
||||
icon: 'none'
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1500)
|
||||
} finally {
|
||||
this.loading = false
|
||||
uni.hideLoading()
|
||||
}
|
||||
},
|
||||
|
||||
// 获取状态文本
|
||||
getStatusText(status, paid) {
|
||||
if (!paid) return '待兑换';
|
||||
|
||||
const statusMap = {
|
||||
0: '待发货',
|
||||
1: '待收货',
|
||||
2: '待评价',
|
||||
3: '已完成'
|
||||
};
|
||||
return statusMap[status] || '未知状态';
|
||||
},
|
||||
|
||||
// 取消订单
|
||||
cancelOrder() {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要取消这个订单吗?积分将退回到您的账户',
|
||||
confirmColor: '#F54900',
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
uni.showLoading({ title: '取消中...' })
|
||||
|
||||
try {
|
||||
await orderCancel(this.orderInfo.id);
|
||||
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '订单已取消',
|
||||
icon: 'success'
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1500)
|
||||
} catch (error) {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: error.msg || '取消失败,请重试',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 确认收货
|
||||
confirmReceipt() {
|
||||
uni.showModal({
|
||||
title: '确认收货',
|
||||
content: '确认已收到商品?',
|
||||
confirmColor: '#F54900',
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
uni.showLoading({ title: '确认中...' })
|
||||
|
||||
try {
|
||||
const result = await orderTake(this.orderInfo.id);
|
||||
console.log('确认收货接口返回:', result)
|
||||
|
||||
uni.hideLoading()
|
||||
|
||||
// 接口返回 code: 200 表示成功
|
||||
if (result.code === 200 || result.code === 0) {
|
||||
uni.showToast({
|
||||
title: '确认收货成功',
|
||||
icon: 'success'
|
||||
})
|
||||
|
||||
// 重新加载订单详情
|
||||
setTimeout(() => {
|
||||
this.loadOrderDetail()
|
||||
}, 1500)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result.msg || '操作失败,请重试',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
uni.hideLoading()
|
||||
console.error('确认收货失败:', error)
|
||||
uni.showToast({
|
||||
title: error.msg || error.message || '操作失败,请重试',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 复制文本
|
||||
copyText(text) {
|
||||
uni.setClipboardData({
|
||||
data: text,
|
||||
success: () => {
|
||||
uni.showToast({
|
||||
title: '已复制',
|
||||
icon: 'success'
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 获取状态图标
|
||||
getStatusIcon(status) {
|
||||
const icons = {
|
||||
1: '⏳', // 待发货
|
||||
2: '🚚', // 待收货
|
||||
3: '✅', // 已完成
|
||||
4: '❌' // 已取消
|
||||
}
|
||||
return icons[status] || '📦'
|
||||
},
|
||||
|
||||
// 获取状态提示
|
||||
getStatusTip(status) {
|
||||
if (!this.orderInfo.paid) {
|
||||
return '请尽快完成支付,积分商品数量有限';
|
||||
}
|
||||
|
||||
const tips = {
|
||||
0: '商家正在准备发货,请耐心等待',
|
||||
1: '商品已发货,请注意查收',
|
||||
2: '请对本次交易进行评价',
|
||||
3: '交易已完成,感谢您的支持'
|
||||
}
|
||||
return tips[status] || ''
|
||||
},
|
||||
|
||||
// 去支付
|
||||
goPay() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/order/order_payment/index?orderNo=${this.orderInfo.order_no}&payPrice=${this.orderInfo.points}`
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.order-detail-page {
|
||||
min-height: 100vh;
|
||||
height: 100vh;
|
||||
background-color: #F5F5F5;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
// 橙色头部
|
||||
.header-section {
|
||||
background-color: #F54900;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
height: 88rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 32rpx;
|
||||
}
|
||||
|
||||
.header-icon {
|
||||
font-size: 48rpx;
|
||||
color: #FFFFFF;
|
||||
font-weight: 300;
|
||||
width: 60rpx;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
flex: 1;
|
||||
font-size: 34rpx;
|
||||
color: #FFFFFF;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.header-placeholder {
|
||||
width: 60rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
padding: 24rpx 32rpx;
|
||||
padding-bottom: 140rpx;
|
||||
box-sizing: border-box;
|
||||
height: calc(100vh - 88rpx - 120rpx);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
// 卡片通用样式
|
||||
.card-section {
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 24rpx;
|
||||
margin-bottom: 24rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// 状态卡片
|
||||
.status-card {
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.status-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
font-size: 36rpx;
|
||||
color: #F54900;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.order-no-text {
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
// 进度条
|
||||
.progress-bar {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.progress-step {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
&.active {
|
||||
.step-icon {
|
||||
background-color: #F54900;
|
||||
border-color: #F54900;
|
||||
|
||||
.icon-text {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
.step-text {
|
||||
color: #F54900;
|
||||
}
|
||||
}
|
||||
|
||||
&.current {
|
||||
.step-icon {
|
||||
background-color: #F54900;
|
||||
border-color: #F54900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.step-icon-wrap {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.step-icon {
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #FFFFFF;
|
||||
border: 4rpx solid #E5E7EB;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.icon-text {
|
||||
font-size: 28rpx;
|
||||
color: #E5E7EB;
|
||||
}
|
||||
|
||||
.step-line {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: calc(50% + 36rpx);
|
||||
width: calc(100% - 72rpx);
|
||||
height: 4rpx;
|
||||
background-color: #E5E7EB;
|
||||
z-index: 1;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.progress-step.active .step-line {
|
||||
background-color: #F54900;
|
||||
}
|
||||
|
||||
.progress-step:last-child .step-line {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.step-text {
|
||||
margin-top: 16rpx;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
// 收货信息卡片
|
||||
.address-card {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
gap: 20rpx;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.address-icon {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.icon-location {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
|
||||
.address-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.address-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.receiver-name {
|
||||
font-size: 30rpx;
|
||||
color: #333333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.receiver-phone {
|
||||
font-size: 30rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.address-text {
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
// 商品信息卡片
|
||||
.goods-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
padding: 32rpx;
|
||||
border-bottom: 1rpx solid #F5F5F5;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.goods-list {
|
||||
padding: 0 32rpx;
|
||||
}
|
||||
|
||||
.goods-item {
|
||||
padding: 32rpx 0;
|
||||
border-bottom: 1rpx solid #F5F5F5;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-name {
|
||||
font-size: 30rpx;
|
||||
color: #333333;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 16rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.goods-price-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.goods-price {
|
||||
font-size: 30rpx;
|
||||
color: #F54900;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.goods-qty {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
// 商品汇总
|
||||
.goods-summary {
|
||||
padding: 24rpx 32rpx;
|
||||
border-top: 1rpx solid #F5F5F5;
|
||||
}
|
||||
|
||||
.summary-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.summary-label {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.summary-value {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.summary-total {
|
||||
font-size: 32rpx;
|
||||
color: #F54900;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
// 订单信息卡片
|
||||
.order-info-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.info-content {
|
||||
padding: 24rpx 32rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.status-value {
|
||||
color: #F54900 !important;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
/* 底部操作栏 - 固定在页面底部 */
|
||||
.bottom-actions {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 999;
|
||||
background-color: #FFFFFF;
|
||||
padding: 20rpx 30rpx;
|
||||
padding-bottom: calc(20rpx + constant(safe-area-inset-bottom));
|
||||
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
||||
border-top: 1rpx solid #EEEEEE;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 20rpx;
|
||||
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
padding: 0 50rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
font-size: 30rpx;
|
||||
border: none;
|
||||
|
||||
&::after {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
background-color: #F5F5F5;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.primary-btn {
|
||||
background-color: #F54900;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user