consumer模块完成度95%,准备部署消费者端测试

This commit is contained in:
cyh666666
2026-03-05 08:45:00 +08:00
parent cceb556c62
commit 7f7f723d93
1043 changed files with 53958 additions and 3445 deletions

View File

@@ -1,28 +1,28 @@
<!-- 消费者端 - 个人中心 -->
<!-- 消费者端 - 个人中心 -->
<template>
<view class="consumer-profile">
<!-- 智能顶部导航栏 - 与消息页保持一致 -->
<view class="smart-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="nav-container">
<!-- 头像 -->
<image
:src="userInfo.avatar_url != '' ? userInfo.avatar_url : '/static/default-avatar.png'"
class="nav-avatar"
@click="editProfile"
/>
<!-- 用户信息横向排列 (名字、积分、余额、优惠券) -->
<view class="nav-user-stats">
<!-- 基础用户信息:头像和昵称 -->
<view class="nav-user-basic" @click="editProfile">
<image
:src="userInfo.avatar_url != '' ? userInfo.avatar_url : '/static/default-avatar.png'"
class="nav-avatar"
/>
<text class="nav-user-name">{{ userInfo.nickname != '' ? userInfo.nickname : userInfo.phone }}</text>
</view>
<!-- 用户资产横向排列 (积分、余额、优惠券) -->
<view class="nav-user-stats">
<view class="nav-stat-item" @click="goToPoints">
<text class="nav-stat-label">积分</text>
<text class="nav-stat-value">{{ userStats.points }}</text>
</view>
<view class="nav-stat-item">
<view class="nav-stat-item" @click="goToWallet">
<text class="nav-stat-label">余额</text>
<text class="nav-stat-value" @click="goToWallet">¥{{ userStats.balance }}</text>
<text class="nav-stat-value">¥{{ userStats.balance }}</text>
</view>
<view class="nav-stat-item" @click="goToCoupons">
@@ -31,7 +31,7 @@
</view>
</view>
<!-- 设置按钮 (右侧) -->
<!-- 设置按钮 (右侧) -->
<view class="nav-actions">
<view class="action-btn" @click="goToSettings">
<text class="action-icon">⚙️</text>
@@ -88,7 +88,10 @@
<!-- 订单状态快捷入口 -->
<view class="order-shortcuts">
<view class="section-title">我的订单</view>
<view class="section-header-row">
<text class="section-title">我的订单</text>
<text class="view-all" @click="goToOrders(currentOrderTab)">查看更多 ></text>
</view>
<view class="order-tabs">
<view class="order-tab" :class="{ active: currentOrderTab === 'all' }" @click="switchOrderTab('all')">
<text class="tab-icon">📋</text>
@@ -117,7 +120,6 @@
<view class="recent-orders">
<view class="section-header">
<text class="section-title">{{ getOrderSectionTitle() }}</text>
<text class="view-all" @click="goToOrders(currentOrderTab)">查看更多 ></text>
</view>
<view v-if="filteredOrders.length === 0" class="empty-orders">
@@ -126,22 +128,36 @@
</view>
<view v-for="order in filteredOrders" :key="order.id" class="order-item" @click="viewOrderDetail(order)">
<view class="order-header">
<text class="order-no">订单号: {{ order.order_no }}</text>
<text class="order-status" :class="getOrderStatusClass(order.status)">{{ getOrderStatusText(order.status) }}</text>
</view>
<view class="order-content">
<image :src="getOrderMainImage(order)" class="order-image" mode="aspectFill" />
<view class="order-info">
<text class="order-title">{{ getOrderTitle(order) }}</text>
<text class="order-amount">¥{{ order.actual_amount }}</text>
<text class="order-time">{{ formatTime(order.created_at) }}</text>
<view class="order-item-header">
<view class="order-shop">
<text class="shop-icon">🏪</text>
<text class="shop-name">{{ getOrderShopName(order) }}</text>
<text class="shop-arrow"></text>
</view>
<view class="status-row">
<text class="order-status-text" :class="getOrderStatusClass(order.status)">{{ getOrderStatusText(order.status) }}</text>
<text class="more-btn" @click.stop="showOrderMenu(order)">⋯</text>
</view>
</view>
<view class="order-actions">
<button v-if="order.status === 1" class="action-btn pay" @click.stop="payOrder(order)">立即支付</button>
<button v-if="order.status === 3" class="action-btn confirm" @click.stop="confirmReceive(order)">确认收货</button>
<button v-if="order.status === 4" class="action-btn review" @click.stop="reviewOrder(order)">评价</button>
<view class="order-item-content">
<image :src="getOrderMainImage(order)" class="order-item-image" mode="aspectFill" />
<view class="order-item-info">
<view class="order-title-row">
<text class="order-item-title">{{ getOrderTitle(order) }}</text>
<text class="order-item-price">¥{{ order.actual_amount }}</text>
</view>
<view class="order-spec-row">
<text class="order-item-spec">{{ getOrderSpec(order) }}</text>
<text class="order-item-num">x{{ getOrderItemCount(order) }}</text>
</view>
<text class="order-item-time">{{ formatDateTime(order.created_at) }}</text>
</view>
</view>
<view class="order-item-actions">
<button v-if="order.status === 1" class="order-action-btn pay" @click.stop="payOrder(order)">立即支付</button>
<button v-if="order.status === 3" class="order-action-btn confirm" @click.stop="confirmReceive(order)">确认收货</button>
<button v-if="order.status === 4" class="order-action-btn review" @click.stop="reviewOrder(order)">评价</button>
<button v-if="order.status === 2 || order.status === 3" class="order-action-btn secondary" @click.stop="viewOrderDetail(order)">查看物流</button>
</view>
</view>
</view>
@@ -290,6 +306,8 @@ type OrderItemType = {
actual_amount: number
created_at: string
ml_order_items: any | null
ml_shops: any | null
items_count: number
}
export default {
@@ -407,13 +425,22 @@ export default {
actualAmount = totalAmount != null ? totalAmount : 0
}
const mlOrderItems = o.get('ml_order_items')
let itemsCount = 0
if (mlOrderItems != null && Array.isArray(mlOrderItems)) {
itemsCount = (mlOrderItems as any[]).length
}
const orderItem: OrderItemType = {
id: o.getString('id') ?? '',
order_no: o.getString('order_no') ?? '',
status: status,
actual_amount: actualAmount,
created_at: o.getString('created_at') ?? '',
ml_order_items: o.get('ml_order_items')
ml_order_items: mlOrderItems,
ml_shops: o.get('ml_shops'),
items_count: itemsCount
}
mappedOrders.push(orderItem)
@@ -629,6 +656,8 @@ export default {
},
getOrderStatusText(status: number): string {
if (status === 6) return '退款中'
if (status === 7) return '已退款'
const statusTexts = ['异常', '待支付', '待发货', '待收货', '已完成', '已取消']
if (status >= 0 && status < statusTexts.length) {
return statusTexts[status]
@@ -637,6 +666,8 @@ export default {
},
getOrderStatusClass(status: number): string {
if (status === 6) return 'refunding'
if (status === 7) return 'refunded'
const statusClasses = ['error', 'pending', 'processing', 'shipping', 'completed', 'cancelled']
if (status >= 0 && status < statusClasses.length) {
return statusClasses[status]
@@ -644,6 +675,242 @@ export default {
return 'error'
},
showOrderMenu(order: OrderItemType) {
const status = order.status
let actions: string[] = []
if (status === 1) {
actions = ['取消订单', '联系卖家']
} else if (status === 2) {
actions = ['提醒发货', '申请退款', '联系卖家']
} else if (status === 3) {
actions = ['查看物流', '确认收货', '申请退款', '联系卖家']
} else if (status === 4) {
actions = ['申请售后', '再次购买', '联系卖家']
} else if (status === 5) {
actions = ['删除订单', '再次购买', '联系卖家']
} else if (status === 6) {
actions = ['退款进度', '联系卖家']
} else if (status === 7) {
actions = ['再次购买', '联系卖家']
}
uni.showActionSheet({
itemList: actions,
success: (res) => {
const action = actions[res.tapIndex]
this.handleOrderAction(order, action)
}
})
},
handleOrderAction(order: OrderItemType, action: string) {
if (action === '取消订单') {
this.cancelOrderAction(order)
} else if (action === '联系卖家') {
this.contactSeller(order)
} else if (action === '提醒发货') {
this.remindShipping(order)
} else if (action === '申请退款' || action === '申请售后') {
this.applyRefund(order)
} else if (action === '查看物流') {
this.viewLogistics(order.id)
} else if (action === '确认收货') {
this.confirmReceive(order)
} else if (action === '再次购买') {
this.repurchase(order)
} else if (action === '删除订单') {
this.deleteOrder(order.id)
} else if (action === '退款进度') {
this.viewRefundProgress(order.id)
}
},
cancelOrderAction(order: OrderItemType) {
uni.showModal({
title: '确认取消',
content: '确定要取消此订单吗?',
success: (res) => {
if (res.confirm) {
uni.showLoading({ title: '取消中...' })
supabaseService.cancelOrder(order.id).then(() => {
uni.hideLoading()
uni.showToast({ title: '订单已取消', icon: 'success' })
this.loadOrders()
}).catch(() => {
uni.hideLoading()
uni.showToast({ title: '取消失败', icon: 'none' })
})
}
}
})
},
contactSeller(order: OrderItemType) {
const merchantId = order.ml_shops != null ? this.getMerchantIdFromOrder(order) : ''
if (merchantId !== '') {
uni.navigateTo({
url: `/pages/mall/consumer/chat?merchantId=${merchantId}`
})
} else {
uni.showToast({ title: '暂无卖家联系方式', icon: 'none' })
}
},
getMerchantIdFromOrder(order: OrderItemType): string {
const shopsRaw = order.ml_shops
if (shopsRaw != null) {
const shopStr = JSON.stringify(shopsRaw)
const shopParsed = JSON.parse(shopStr)
if (shopParsed != null) {
const shopObj = shopParsed as UTSJSONObject
return shopObj.getString('merchant_id') ?? ''
}
}
return ''
},
remindShipping(order: OrderItemType) {
uni.showLoading({ title: '提醒中...' })
const merchantId = order.ml_shops != null ? this.getMerchantIdFromOrder(order) : ''
if (merchantId !== '') {
const message = `你好,我的订单[${order.order_no}]还没有发货,请尽快安排,谢谢。`
supabaseService.sendChatMessage(message, merchantId).then(() => {
uni.hideLoading()
uni.showToast({ title: '已提醒卖家发货', icon: 'success' })
}).catch(() => {
uni.hideLoading()
uni.showToast({ title: '提醒失败', icon: 'none' })
})
} else {
uni.hideLoading()
uni.showToast({ title: '无法联系卖家', icon: 'none' })
}
},
applyRefund(order: OrderItemType) {
uni.navigateTo({
url: `/pages/mall/consumer/apply-refund?orderId=${order.id}`
})
},
viewLogistics(orderId: string) {
uni.navigateTo({
url: `/pages/mall/consumer/logistics?orderId=${orderId}`
})
},
repurchase(order: OrderItemType) {
uni.showLoading({ title: '处理中...' })
const itemsRaw = order.ml_order_items
if (itemsRaw == null || (itemsRaw as any[]).length === 0) {
uni.hideLoading()
uni.showToast({ title: '订单无商品', icon: 'none' })
return
}
const items = itemsRaw as any[]
let completed = 0
const total = items.length
let successCount = 0
for (let i = 0; i < items.length; i++) {
const itemStr = JSON.stringify(items[i])
const itemParsed = JSON.parse(itemStr)
if (itemParsed == null) {
completed++
if (completed === total) {
uni.hideLoading()
if (successCount > 0) {
uni.showToast({ title: `已添加${successCount}件商品`, icon: 'success' })
} else {
uni.showToast({ title: '添加失败', icon: 'none' })
}
}
continue
}
const itemObj = itemParsed as UTSJSONObject
const productId = itemObj.getString('product_id') ?? ''
const merchantId = order.ml_shops != null ? this.getMerchantIdFromOrder(order) : ''
if (productId !== '') {
supabaseService.addToCart(productId, 1, '', merchantId).then((success) => {
completed++
if (success) successCount++
if (completed === total) {
uni.hideLoading()
if (successCount > 0) {
uni.showToast({ title: `已添加${successCount}件商品`, icon: 'success' })
} else {
uni.showToast({ title: '添加失败', icon: 'none' })
}
}
}).catch(() => {
completed++
if (completed === total) {
uni.hideLoading()
if (successCount > 0) {
uni.showToast({ title: `已添加${successCount}件商品`, icon: 'success' })
} else {
uni.showToast({ title: '添加失败', icon: 'none' })
}
}
})
} else {
completed++
if (completed === total) {
uni.hideLoading()
if (successCount > 0) {
uni.showToast({ title: `已添加${successCount}件商品`, icon: 'success' })
} else {
uni.showToast({ title: '添加失败', icon: 'none' })
}
}
}
}
},
deleteOrder(orderId: string) {
uni.showModal({
title: '删除订单',
content: '确定要删除此订单吗?',
success: (res) => {
if (res.confirm) {
uni.showLoading({ title: '删除中...' })
supabaseService.deleteOrder(orderId).then(() => {
uni.hideLoading()
uni.showToast({ title: '订单已删除', icon: 'success' })
this.loadOrders()
}).catch(() => {
uni.hideLoading()
uni.showToast({ title: '删除失败', icon: 'none' })
})
}
}
})
},
viewRefundProgress(orderId: string) {
uni.navigateTo({
url: `/pages/mall/consumer/refund?orderId=${orderId}`
})
},
getOrderShopName(order: OrderItemType): string {
const shopsRaw = order.ml_shops
if (shopsRaw != null) {
const shopStr = JSON.stringify(shopsRaw)
const shopParsed = JSON.parse(shopStr)
if (shopParsed != null) {
const shopObj = shopParsed as UTSJSONObject
const name = shopObj.getString('shop_name')
if (name != null && name !== '') return name
}
}
return '自营店铺'
},
getOrderMainImage(order: OrderItemType): string {
const itemsRaw = order.ml_order_items
if (itemsRaw == null) return '/static/product1.jpg'
@@ -675,14 +942,80 @@ export default {
const pName = itemObj.getString('product_name')
const name = (pName != null && pName !== '') ? pName : '商品'
if (items.length > 1) {
return name + ' 等' + items.length + '件商品'
}
return name
}
return '精选商品'
},
getOrderSpec(order: OrderItemType): string {
const itemsRaw = order.ml_order_items
if (itemsRaw == null) return ''
const items = itemsRaw as any[]
if (items.length > 0) {
const firstItem = items[0]
const itemStr = JSON.stringify(firstItem)
const itemParsed = JSON.parse(itemStr)
if (itemParsed == null) return ''
const itemObj = itemParsed as UTSJSONObject
const specRaw = itemObj.get('specifications')
if (specRaw == null) return ''
if (typeof specRaw === 'string') {
const specStr = specRaw as string
if (specStr.startsWith('{')) {
try {
const specObj = JSON.parse(specStr) as UTSJSONObject
const parts: string[] = []
const color = specObj.get('Color')
if (color != null) parts.push('颜色: ' + color)
const size = specObj.get('Size')
if (size != null) parts.push('尺码: ' + size)
if (parts.length > 0) return parts.join(' ')
return specStr.replace(/[{}"]/g, '')
} catch (e) {
return specStr
}
}
return specStr
}
return JSON.stringify(specRaw).replace(/[{}"]/g, '')
}
return ''
},
getOrderItemCount(order: OrderItemType): number {
if (order.items_count != null && order.items_count > 0) {
return order.items_count
}
return 1
},
getOrderShopName(order: OrderItemType): string {
const shopsRaw = order.ml_shops
if (shopsRaw != null) {
const shopStr = JSON.stringify(shopsRaw)
const shopParsed = JSON.parse(shopStr)
if (shopParsed != null) {
const shopObj = shopParsed as UTSJSONObject
const name = shopObj.getString('shop_name')
if (name != null && name !== '') return name
}
}
return '自营店铺'
},
formatDateTime(timeStr: string): string {
if (timeStr == null || timeStr === '') return ''
const date = new Date(timeStr)
const y = date.getFullYear()
const m = (date.getMonth() + 1).toString().padStart(2, '0')
const d = date.getDate().toString().padStart(2, '0')
const h = date.getHours().toString().padStart(2, '0')
const i = date.getMinutes().toString().padStart(2, '0')
return `${y}-${m}-${d} ${h}:${i}`
},
formatTime(timeStr: string): string {
const date = new Date(timeStr)
const now = new Date()
@@ -753,11 +1086,21 @@ export default {
content: '确认已收到商品吗?',
success: (res) => {
if (res.confirm) {
uni.showToast({
title: '确认收货成功',
icon: 'success'
uni.showLoading({ title: '处理中...' })
supabaseService.confirmOrderReceived(order.id).then(() => {
uni.hideLoading()
uni.showToast({
title: '确认收货成功',
icon: 'success'
})
this.loadOrders()
}).catch(() => {
uni.hideLoading()
uni.showToast({
title: '操作失败',
icon: 'none'
})
})
this.refreshData()
}
}
})
@@ -891,9 +1234,9 @@ export default {
top: 0;
left: 0;
right: 0;
background-color: #4CAF50;
background-color: #ff5000;
z-index: 1000;
box-shadow: 0 2px 12px rgba(76, 175, 80, 0.15);
box-shadow: 0 2px 12px rgba(255, 80, 0, 0.15);
display: flex;
flex-direction: column;
justify-content: flex-start;
@@ -912,23 +1255,28 @@ export default {
}
/* 导航栏用户信息区域 */
.nav-user-basic {
display: flex;
flex-direction: row;
align-items: center;
flex-shrink: 0;
margin-right: 8px;
}
.nav-user-stats {
flex: 1;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start; /* 靠左对齐,紧跟头像 */
margin-right: 12px;
overflow: hidden; /* 防止溢出 */
justify-content: flex-end; /* 将积分、余额、券推向右侧,但在设置按钮之前 */
margin-right: 8px;
}
.nav-user-name {
font-size: 16px;
font-size: 14px;
font-weight: bold;
color: white;
margin-right: 12px;
/* max-width: 30%; REMOVED */
width: 100px; /* Use fixed width approx */
width: 70px; /* 进一步压缩名字宽度 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@@ -938,31 +1286,31 @@ export default {
display: flex;
flex-direction: row;
align-items: center;
background: rgba(255, 255, 255, 0.2);
border-radius: 12px;
padding: 2px 8px;
margin-right: 8px;
flex-shrink: 0; /* 防止被压缩 */
background: rgba(255, 255, 255, 0.15); /* 降低透明度更清爽 */
border-radius: 10px;
padding: 2px 6px;
margin-right: 4px; /* 减小间距 */
flex-shrink: 0;
}
.nav-stat-label {
font-size: 11px;
color: rgba(255, 255, 255, 0.9);
margin-right: 4px;
font-size: 10px; /* 调小字体 */
color: rgba(255, 255, 255, 0.85);
margin-right: 2px;
}
.nav-stat-value {
font-size: 12px;
font-size: 11px; /* 调小字体 */
font-weight: bold;
color: white;
}
.nav-avatar {
width: 36px;
height: 36px;
border-radius: 18px;
border: 2px solid rgba(255, 255, 255, 0.8);
margin-right: 12px;
width: 32px; /* 缩小头像 */
height: 32px;
border-radius: 16px;
border: 1.5px solid rgba(255, 255, 255, 0.8);
margin-right: 6px;
flex-shrink: 0;
}
@@ -1010,6 +1358,23 @@ export default {
margin-bottom: 16px;
}
.section-header-row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin-bottom: 16px;
}
.section-header-row .section-title {
margin-bottom: 0;
}
.view-all {
font-size: 14px;
color: #999;
}
.order-tabs {
display: flex;
flex-direction: row; /* 显式横向排列 */
@@ -1041,12 +1406,12 @@ export default {
/* 选中状态的Tab */
.order-tab.active .tab-icon,
.order-tab.active .tab-text {
color: #4CAF50;
color: #ff5000;
font-weight: bold;
}
.order-tab.active {
background-color: #f0f9f0;
background-color: #fff8f5;
border-radius: 8px;
}
@@ -1054,7 +1419,7 @@ export default {
position: absolute;
top: 0;
right: 10%; /* 调整位置 */
background-color: #ff4444;
background-color: #ff5000;
color: #fff;
font-size: 10px;
padding: 1px 5px;
@@ -1085,114 +1450,200 @@ export default {
}
.order-item {
padding: 25rpx 0;
border-bottom: 1rpx solid #f5f5f5;
background-color: #fff;
border-radius: 16rpx;
padding: 24rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
}
.order-item:last-child {
border-bottom: none;
}
.order-header {
.order-item-header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-bottom: 15rpx;
margin-bottom: 20rpx;
}
.order-no {
font-size: 26rpx;
color: #333;
}
.order-status {
font-size: 24rpx;
padding: 6rpx 12rpx;
border-radius: 10rpx;
color: #fff;
}
.order-status.pending {
background-color: #ffa726;
}
.order-status.processing {
background-color: #2196f3;
}
.order-status.shipping {
background-color: #9c27b0;
}
.order-status.completed {
background-color: #4caf50;
}
.order-content {
.status-row {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 15rpx;
}
.order-image {
width: 100rpx;
height: 100rpx;
border-radius: 8rpx;
margin-right: 20rpx;
.more-btn {
font-size: 18px;
color: #999;
margin-left: 8px;
padding: 0 5px;
}
.order-info {
flex: 1;
.order-shop {
display: flex;
flex-direction: row;
align-items: center;
}
.order-title {
font-size: 26rpx;
color: #333;
margin-bottom: 8rpx;
.shop-icon {
font-size: 32rpx;
margin-right: 8rpx;
}
.order-amount {
.shop-name {
font-size: 28rpx;
color: #ff4444;
font-weight: bold;
margin-bottom: 5rpx;
color: #333;
}
.order-time {
font-size: 22rpx;
.shop-arrow {
font-size: 28rpx;
color: #ccc;
margin-left: 4rpx;
}
.order-status-text {
font-size: 26rpx;
font-weight: bold;
}
.order-status-text.pending {
color: #ff5000;
}
.order-status-text.processing {
color: #ff9500;
}
.order-status-text.shipping {
color: #007aff;
}
.order-status-text.completed {
color: #34c759;
}
.order-status-text.refunding {
color: #ff9500;
}
.order-status-text.refunded {
color: #999;
}
.order-actions {
.order-status-text.cancelled {
color: #999;
}
.order-item-content {
display: flex;
justify-content: flex-end;
/* gap: 15rpx; REMOVED */
flex-direction: row;
margin-bottom: 24rpx;
}
.order-actions .action-btn {
margin-left: 15px; /* Replace gap */
.order-item-image {
width: 140rpx;
height: 140rpx;
border-radius: 12rpx;
margin-right: 20rpx;
background-color: #f8f8f8;
}
.action-btn {
padding: 12rpx 25rpx;
border-radius: 20rpx;
.order-item-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: flex-start;
}
.order-title-row {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 12rpx;
}
.order-item-title {
flex: 1;
font-size: 28rpx;
color: #333;
line-height: 1.4;
margin-right: 20rpx;
lines: 2;
text-overflow: ellipsis;
}
.order-item-price {
font-size: 32rpx;
color: #333;
font-weight: bold;
text-align: right;
}
.order-spec-row {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-top: 4rpx;
margin-bottom: 8rpx;
}
.order-item-spec {
flex: 1;
font-size: 24rpx;
border: none;
color: #999;
margin-right: 12rpx;
lines: 1;
text-overflow: ellipsis;
}
.action-btn.pay {
background-color: #ff4444;
color: #fff;
.order-item-time {
font-size: 22rpx;
color: #999;
margin-top: auto;
}
.action-btn.confirm {
background-color: #4caf50;
color: #fff;
.order-item-num {
font-size: 24rpx;
color: #999;
}
.action-btn.review {
background-color: #ffa726;
.order-item-actions {
display: flex;
flex-direction: row;
justify-content: flex-end;
}
.order-action-btn {
margin-left: 16rpx;
padding: 10rpx 28rpx;
border-radius: 30rpx;
font-size: 24rpx;
border: 1px solid #ddd;
background-color: #fff;
}
.order-action-btn.pay {
background-color: #ff5000;
color: #fff;
border-color: #ff5000;
}
.order-action-btn.confirm {
background-color: #ff5000;
color: #fff;
border-color: #ff5000;
}
.order-action-btn.review {
color: #ff5000;
border-color: #ff5000;
}
.order-action-btn.secondary {
color: #666;
border-color: #ddd;
}
.service-grid {
@@ -1227,7 +1678,7 @@ export default {
position: absolute;
top: -5rpx;
right: 10rpx;
background-color: #ff4444;
background-color: #ff5000;
color: #fff;
font-size: 18rpx;
padding: 4rpx 6rpx;
@@ -1332,3 +1783,4 @@ export default {
color: #999;
}
</style>