Initial commit of akmon project

This commit is contained in:
2026-01-20 08:04:15 +08:00
commit 77a2bab985
1309 changed files with 343305 additions and 0 deletions

View File

@@ -0,0 +1,590 @@
<!-- 消费者端 - 订单详情页 -->
<template>
<view class="order-detail-page">
<!-- 订单状态 -->
<view class="order-status">
<view class="status-icon">
<text class="status-emoji">{{ getStatusIcon() }}</text>
</view>
<view class="status-info">
<text class="status-text">{{ getStatusText() }}</text>
<text class="status-desc">{{ getStatusDesc() }}</text>
</view>
</view>
<!-- 配送信息 -->
<view v-if="order.status >= 2" class="delivery-info">
<view class="delivery-header">
<text class="delivery-title">配送信息</text>
</view>
<view class="delivery-address">
<view class="address-info">
<text class="recipient">{{ getDeliveryAddress().name }}</text>
<text class="phone">{{ getDeliveryAddress().phone }}</text>
</view>
<text class="address-detail">{{ getDeliveryAddress().detail }}</text>
</view>
<view v-if="deliveryInfo.courier_name" class="courier-info">
<text class="courier-label">配送员:</text>
<text class="courier-name">{{ deliveryInfo.courier_name }}</text>
<text class="courier-phone">{{ deliveryInfo.courier_phone }}</text>
</view>
</view>
<!-- 商品信息 -->
<view class="order-products">
<view class="shop-header">
<text class="shop-name">{{ merchant.shop_name }}</text>
</view>
<view v-for="item in orderItems" :key="item.id" class="product-item">
<image :src="item.product_image || '/static/default-product.png'" class="product-image" />
<view class="product-info">
<text class="product-name">{{ item.product_name }}</text>
<text v-if="item.sku_specifications" class="product-spec">{{ getSpecText(item.sku_specifications) }}</text>
<view class="price-quantity">
<text class="product-price">¥{{ item.price }}</text>
<text class="product-quantity">×{{ item.quantity }}</text>
</view>
</view>
</view>
</view>
<!-- 订单信息 -->
<view class="order-info">
<view class="info-row">
<text class="info-label">订单编号</text>
<text class="info-value">{{ order.order_no }}</text>
</view>
<view class="info-row">
<text class="info-label">下单时间</text>
<text class="info-value">{{ formatTime(order.created_at) }}</text>
</view>
<view class="info-row">
<text class="info-label">支付方式</text>
<text class="info-value">{{ getPaymentMethodText() }}</text>
</view>
</view>
<!-- 费用明细 -->
<view class="cost-detail">
<view class="cost-row">
<text class="cost-label">商品总额</text>
<text class="cost-value">¥{{ order.total_amount }}</text>
</view>
<view class="cost-row">
<text class="cost-label">优惠金额</text>
<text class="cost-value">-¥{{ order.discount_amount }}</text>
</view>
<view class="cost-row">
<text class="cost-label">配送费</text>
<text class="cost-value">¥{{ order.delivery_fee }}</text>
</view>
<view class="cost-row total">
<text class="cost-label">实付金额</text>
<text class="cost-value">¥{{ order.actual_amount }}</text>
</view>
</view>
<!-- 底部操作 -->
<view class="bottom-actions">
<button v-if="order.status === 1" class="pay-btn" @click="payOrder">立即支付</button>
<button v-if="order.status === 2" class="remind-btn" @click="remindDelivery">提醒发货</button>
<button v-if="order.status === 3" class="confirm-btn" @click="confirmReceive">确认收货</button>
<button v-if="order.status === 4" class="review-btn" @click="goToReview">评价商品</button>
<button v-if="order.status <= 2" class="cancel-btn" @click="cancelOrder">取消订单</button>
<button class="service-btn" @click="contactService">联系客服</button>
</view>
</view>
</template>
<script>
import { OrderType, OrderItemType, MerchantType } from '@/types/mall-types.uts'
export default {
data() {
return {
order: {
id: '',
order_no: '',
user_id: '',
merchant_id: '',
status: 0,
total_amount: 0,
discount_amount: 0,
delivery_fee: 0,
actual_amount: 0,
payment_method: 0,
payment_status: 0,
delivery_address: {},
created_at: ''
} as OrderType,
orderItems: [] as Array<OrderItemType & { product_image: string }>,
merchant: {
id: '',
user_id: '',
shop_name: '',
shop_logo: '',
shop_banner: '',
shop_description: '',
contact_name: '',
contact_phone: '',
shop_status: 0,
rating: 0,
total_sales: 0,
created_at: ''
} as MerchantType,
deliveryInfo: {
courier_name: '',
courier_phone: '',
tracking_no: ''
}
}
},
onLoad(options: any) {
const orderId = options.orderId as string
if (orderId) {
this.loadOrderDetail(orderId)
}
},
methods: {
loadOrderDetail(orderId: string) {
// 模拟加载订单详情数据
this.order = {
id: orderId,
order_no: 'ORD202401150001',
user_id: 'user_001',
merchant_id: 'merchant_001',
status: 3, // 1:待支付 2:待发货 3:待收货 4:已完成 5:已取消
total_amount: 299.98,
discount_amount: 30.00,
delivery_fee: 8.00,
actual_amount: 277.98,
payment_method: 1, // 1:微信支付 2:支付宝 3:余额
payment_status: 1,
delivery_address: {
name: '张三',
phone: '13800138000',
detail: '北京市朝阳区某某街道某某小区1号楼101室'
},
created_at: '2024-01-15 14:30:00'
}
this.orderItems = [
{
id: 'item_001',
order_id: orderId,
product_id: 'product_001',
sku_id: 'sku_001',
product_name: '精选好物商品',
sku_specifications: { color: '红色', size: 'M' },
price: 199.99,
quantity: 1,
total_amount: 199.99,
product_image: '/static/product1.jpg'
},
{
id: 'item_002',
order_id: orderId,
product_id: 'product_002',
sku_id: 'sku_002',
product_name: '优质配件',
sku_specifications: { type: '标准版' },
price: 99.99,
quantity: 1,
total_amount: 99.99,
product_image: '/static/product2.jpg'
}
]
this.merchant = {
id: 'merchant_001',
user_id: 'user_001',
shop_name: '优质好店',
shop_logo: '/static/shop-logo.png',
shop_banner: '/static/shop-banner.png',
shop_description: '专注品质生活',
contact_name: '店主小王',
contact_phone: '13800138000',
shop_status: 1,
rating: 4.8,
total_sales: 15680,
created_at: '2023-06-01'
}
if (this.order.status >= 3) {
this.deliveryInfo = {
courier_name: '李师傅',
courier_phone: '13900139000',
tracking_no: 'YT123456789'
}
}
},
getStatusIcon(): string {
const icons = ['⏳', '💰', '📦', '🚚', '✅', '❌']
return icons[this.order.status] || '⏳'
},
getStatusText(): string {
const statusTexts = ['订单异常', '待支付', '待发货', '待收货', '已完成', '已取消']
return statusTexts[this.order.status] || '未知状态'
},
getStatusDesc(): string {
const statusDescs = [
'订单状态异常',
'请在24小时内完成支付',
'商家正在准备发货',
'商品正在配送中,请耐心等待',
'订单已完成,感谢您的购买',
'订单已取消'
]
return statusDescs[this.order.status] || ''
},
getDeliveryAddress(): any {
return this.order.delivery_address as any
},
getSpecText(specifications: any): string {
if (!specifications) return ''
return Object.keys(specifications).map(key => `${key}: ${specifications[key]}`).join(', ')
},
formatTime(timeStr: string): string {
return timeStr.replace('T', ' ').split('.')[0]
},
getPaymentMethodText(): string {
const methods = ['', '微信支付', '支付宝', '余额支付']
return methods[this.order.payment_method || 0] || '未知'
},
payOrder() {
uni.showModal({
title: '确认支付',
content: `确认支付 ¥${this.order.actual_amount} 吗?`,
success: (res) => {
if (res.confirm) {
// 模拟支付
uni.showLoading({ title: '支付中...' })
setTimeout(() => {
uni.hideLoading()
this.order.status = 2
uni.showToast({
title: '支付成功',
icon: 'success'
})
}, 2000)
}
}
})
},
remindDelivery() {
uni.showToast({
title: '已提醒商家发货',
icon: 'success'
})
},
confirmReceive() {
uni.showModal({
title: '确认收货',
content: '确认已收到商品吗?',
success: (res) => {
if (res.confirm) {
this.order.status = 4
uni.showToast({
title: '确认收货成功',
icon: 'success'
})
}
}
})
},
goToReview() {
uni.navigateTo({
url: `/pages/mall/consumer/product-review?orderId=${this.order.id}`
})
},
cancelOrder() {
uni.showModal({
title: '取消订单',
content: '确定要取消这个订单吗?',
success: (res) => {
if (res.confirm) {
this.order.status = 5
uni.showToast({
title: '订单已取消',
icon: 'success'
})
}
}
})
},
contactService() {
uni.navigateTo({
url: `/pages/mall/service/chat?orderId=${this.order.id}`
})
}
}
}
</script>
<style>
.order-detail-page {
background-color: #f5f5f5;
min-height: 100vh;
padding-bottom: 120rpx;
}
.order-status {
background-color: #fff;
padding: 40rpx 30rpx;
margin-bottom: 20rpx;
display: flex;
align-items: center;
}
.status-icon {
width: 100rpx;
height: 100rpx;
background-color: #f0f8ff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 30rpx;
}
.status-emoji {
font-size: 48rpx;
}
.status-info {
flex: 1;
}
.status-text {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.status-desc {
font-size: 26rpx;
color: #666;
}
.delivery-info {
background-color: #fff;
padding: 30rpx;
margin-bottom: 20rpx;
}
.delivery-header {
margin-bottom: 20rpx;
}
.delivery-title {
font-size: 30rpx;
font-weight: bold;
color: #333;
}
.delivery-address {
padding: 20rpx 0;
border-bottom: 1rpx solid #f5f5f5;
}
.address-info {
display: flex;
margin-bottom: 10rpx;
}
.recipient {
font-size: 28rpx;
color: #333;
margin-right: 30rpx;
}
.phone {
font-size: 28rpx;
color: #666;
}
.address-detail {
font-size: 26rpx;
color: #666;
line-height: 1.4;
}
.courier-info {
padding: 20rpx 0;
display: flex;
align-items: center;
}
.courier-label {
font-size: 26rpx;
color: #666;
margin-right: 10rpx;
}
.courier-name {
font-size: 26rpx;
color: #333;
margin-right: 30rpx;
}
.courier-phone {
font-size: 26rpx;
color: #007aff;
}
.order-products {
background-color: #fff;
margin-bottom: 20rpx;
}
.shop-header {
padding: 20rpx 30rpx;
border-bottom: 1rpx solid #f5f5f5;
}
.shop-name {
font-size: 28rpx;
color: #333;
}
.product-item {
display: flex;
padding: 30rpx;
border-bottom: 1rpx solid #f5f5f5;
}
.product-item:last-child {
border-bottom: none;
}
.product-image {
width: 120rpx;
height: 120rpx;
border-radius: 10rpx;
margin-right: 20rpx;
}
.product-info {
flex: 1;
}
.product-name {
font-size: 28rpx;
color: #333;
margin-bottom: 10rpx;
line-height: 1.3;
}
.product-spec {
font-size: 24rpx;
color: #999;
margin-bottom: 15rpx;
}
.price-quantity {
display: flex;
justify-content: space-between;
align-items: center;
}
.product-price {
font-size: 28rpx;
color: #ff4444;
font-weight: bold;
}
.product-quantity {
font-size: 26rpx;
color: #666;
}
.order-info, .cost-detail {
background-color: #fff;
padding: 30rpx;
margin-bottom: 20rpx;
}
.info-row, .cost-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15rpx 0;
}
.info-label, .cost-label {
font-size: 28rpx;
color: #666;
}
.info-value, .cost-value {
font-size: 28rpx;
color: #333;
}
.cost-row.total {
border-top: 1rpx solid #f5f5f5;
margin-top: 10rpx;
padding-top: 20rpx;
}
.cost-row.total .cost-label,
.cost-row.total .cost-value {
font-weight: bold;
color: #ff4444;
}
.bottom-actions {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: #fff;
padding: 20rpx 30rpx;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.1);
display: flex;
gap: 20rpx;
}
.bottom-actions button {
flex: 1;
height: 70rpx;
border-radius: 35rpx;
font-size: 26rpx;
border: none;
}
.pay-btn, .confirm-btn {
background-color: #ff4444;
color: #fff;
}
.remind-btn, .review-btn {
background-color: #ffa726;
color: #fff;
}
.cancel-btn {
background-color: #f5f5f5;
color: #666;
}
.service-btn {
background-color: #007aff;
color: #fff;
}
</style>