Some checks reported errors
continuous-integration/drone/push Build encountered an error
789 lines
19 KiB
Vue
789 lines
19 KiB
Vue
<template>
|
||
<view class="detail-page">
|
||
<!-- 自定义导航栏 -->
|
||
<view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
|
||
<view class="navbar-content">
|
||
<view class="nav-back" @click="goBack">
|
||
<image class="back-icon" src="/static/ic_back.png" mode="aspectFit"></image>
|
||
</view>
|
||
<text class="navbar-title">订单详情</text>
|
||
<view class="nav-placeholder"></view>
|
||
</view>
|
||
</view>
|
||
<view :style="{ height: (statusBarHeight + 44) + 'px' }"></view>
|
||
<!-- 页面标题 -->
|
||
<view class="page-title">
|
||
<text>我的{{ getTypeLabel(order.orderType) }}订单详情</text>
|
||
</view>
|
||
|
||
<!-- 订单状态 -->
|
||
<view class="status-bar" :class="getStatusClass(order.status)">
|
||
<text class="status-text">{{ getStatusLabel(order.status) }}</text>
|
||
</view>
|
||
|
||
<!-- 订单基本信息 -->
|
||
<view class="info-section">
|
||
<view class="section-title"><text>订单信息</text></view>
|
||
|
||
<view class="info-row">
|
||
<text class="info-label">订单ID</text>
|
||
<text class="info-value">{{ order.orderNo || '-' }}</text>
|
||
</view>
|
||
|
||
<view class="info-row" v-if="order.itemName">
|
||
<text class="info-label">物品/事项</text>
|
||
<text class="info-value">{{ order.itemName }}</text>
|
||
</view>
|
||
|
||
<view class="info-row" v-if="order.pickupLocation">
|
||
<text class="info-label">取货地点</text>
|
||
<text class="info-value">{{ order.pickupLocation }}</text>
|
||
</view>
|
||
|
||
<view class="info-row" v-if="order.deliveryLocation">
|
||
<text class="info-label">送达地点</text>
|
||
<text class="info-value">{{ order.deliveryLocation }}</text>
|
||
</view>
|
||
|
||
<view class="info-row" v-if="order.remark">
|
||
<text class="info-label">备注</text>
|
||
<text class="info-value">{{ order.remark }}</text>
|
||
</view>
|
||
|
||
<view class="info-row" v-if="order.phone">
|
||
<text class="info-label">联系方式</text>
|
||
<text class="info-value">{{ order.phone }}</text>
|
||
</view>
|
||
|
||
<view class="info-row" v-if="order.goodsAmount">
|
||
<text class="info-label">商品金额</text>
|
||
<text class="info-value price">¥{{ order.goodsAmount }}</text>
|
||
</view>
|
||
|
||
<view class="info-row">
|
||
<text class="info-label">跑腿佣金</text>
|
||
<text class="info-value price">¥{{ order.commission }}</text>
|
||
</view>
|
||
|
||
<view class="info-row" v-if="order.platformFee != null">
|
||
<text class="info-label">平台抽成</text>
|
||
<text class="info-value">-¥{{ order.platformFee }}</text>
|
||
</view>
|
||
|
||
<view class="info-row" v-if="order.netEarning != null">
|
||
<text class="info-label">跑腿实得</text>
|
||
<text class="info-value highlight">¥{{ order.netEarning }}</text>
|
||
</view>
|
||
|
||
<view class="info-row">
|
||
<text class="info-label">支付总额</text>
|
||
<text class="info-value price">¥{{ order.totalAmount }}</text>
|
||
</view>
|
||
|
||
<view class="info-row">
|
||
<text class="info-label">下单时间</text>
|
||
<text class="info-value">{{ formatTime(order.createdAt) }}</text>
|
||
</view>
|
||
|
||
<!-- 接单后显示 -->
|
||
<view class="info-row">
|
||
<text class="info-label">接单时间</text>
|
||
<text class="info-value">{{ order.acceptedAt ? formatTime(order.acceptedAt) : '-' }}</text>
|
||
</view>
|
||
|
||
<view class="info-row">
|
||
<text class="info-label">跑腿昵称</text>
|
||
<text class="info-value">{{ order.runnerNickname || '-' }}</text>
|
||
</view>
|
||
|
||
<view class="info-row">
|
||
<text class="info-label">跑腿UID</text>
|
||
<text class="info-value">{{ order.runnerId || '-' }}</text>
|
||
</view>
|
||
|
||
<!-- 完成后显示 -->
|
||
<view class="info-row">
|
||
<text class="info-label">完成时间</text>
|
||
<text class="info-value">{{ order.completedAt ? formatTime(order.completedAt) : '-' }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 完成凭证 -->
|
||
<view class="info-section" v-if="order.completionProof">
|
||
<view class="section-title"><text>完成凭证</text></view>
|
||
<image
|
||
class="proof-image"
|
||
:src="order.completionProof"
|
||
mode="aspectFit"
|
||
@click="previewImage(order.completionProof)"
|
||
></image>
|
||
</view>
|
||
|
||
<!-- 美食街订单额外信息 -->
|
||
<view class="info-section" v-if="order.orderType === 'Food' && foodItems.length > 0">
|
||
<view class="section-title"><text>美食街订单详情</text></view>
|
||
|
||
<view class="info-row" v-if="order.packingFee">
|
||
<text class="info-label">打包费</text>
|
||
<text class="info-value price">¥{{ order.packingFee }}</text>
|
||
</view>
|
||
|
||
<!-- 按门店分组展示菜品 -->
|
||
<view v-for="(group, idx) in groupedFoodItems" :key="idx" class="shop-group">
|
||
<text class="shop-name">{{ group.shopName }}</text>
|
||
<view v-for="item in group.items" :key="item.id" class="dish-item">
|
||
<image v-if="item.dishPhoto" class="dish-photo" :src="item.dishPhoto" mode="aspectFill"></image>
|
||
<view class="dish-info">
|
||
<text class="dish-name">{{ item.dishName }}</text>
|
||
<text class="dish-price">¥{{ item.unitPrice }} × {{ item.quantity }}份</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="info-row">
|
||
<text class="info-label">总份数</text>
|
||
<text class="info-value">{{ totalQuantity }}份</text>
|
||
</view>
|
||
<view class="info-row">
|
||
<text class="info-label">垫付总金额</text>
|
||
<text class="info-value price">¥{{ order.goodsAmount }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 申诉处理结果 -->
|
||
<view class="info-section" v-if="appeals.length > 0">
|
||
<view class="section-title"><text>申诉处理结果</text></view>
|
||
<view v-for="appeal in appeals" :key="appeal.id" class="appeal-item">
|
||
<text class="appeal-result">{{ appeal.result }}</text>
|
||
<text class="appeal-time">{{ formatTime(appeal.createdAt) }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 底部操作按钮 -->
|
||
<view class="bottom-actions">
|
||
<!-- 待接单:取消订单 -->
|
||
<template v-if="order.status === 'Pending'">
|
||
<view class="action-btn btn-cancel" @click="onCancelOrder">
|
||
<text>取消订单</text>
|
||
</view>
|
||
</template>
|
||
|
||
<!-- 进行中:单主看联系跑腿,跑腿看完成订单+联系单主 -->
|
||
<template v-else-if="order.status === 'InProgress'">
|
||
<view v-if="!isOwner" class="action-btn btn-primary" @click="goCompleteOrder">
|
||
<text>完成订单</text>
|
||
</view>
|
||
<view class="action-btn btn-secondary" @click="goChat">
|
||
<text>{{ isOwner ? '联系跑腿' : '联系单主' }}</text>
|
||
</view>
|
||
</template>
|
||
|
||
<!-- 已完成:单主可评价+联系跑腿,跑腿可联系单主 -->
|
||
<template v-else-if="order.status === 'Completed'">
|
||
<view v-if="isOwner && !order.isReviewed" class="action-btn btn-primary" @click="openReview">
|
||
<text>评价跑腿</text>
|
||
</view>
|
||
<view class="action-btn btn-secondary" @click="goChat">
|
||
<text>{{ isOwner ? '联系跑腿' : '联系单主' }}</text>
|
||
</view>
|
||
</template>
|
||
|
||
<!-- 待确认:单主看到确认/拒绝按钮,跑腿看到联系单主 -->
|
||
<template v-else-if="order.status === 'WaitConfirm'">
|
||
<template v-if="isOwner">
|
||
<view class="action-btn btn-cancel" @click="onRejectComplete">
|
||
<text>订单未完成</text>
|
||
</view>
|
||
<view class="action-btn btn-primary" @click="onConfirmComplete">
|
||
<text>确认订单完成</text>
|
||
</view>
|
||
</template>
|
||
<view class="action-btn btn-secondary" @click="goChat">
|
||
<text>{{ isOwner ? '联系跑腿' : '联系单主' }}</text>
|
||
</view>
|
||
</template>
|
||
</view>
|
||
|
||
<!-- 评价弹窗 -->
|
||
<view class="modal-mask" v-if="showReviewModal" @click="showReviewModal = false">
|
||
<view class="modal-content" @click.stop>
|
||
<text class="modal-title">评价跑腿</text>
|
||
<view class="star-row">
|
||
<text
|
||
v-for="star in 5"
|
||
:key="star"
|
||
class="star"
|
||
:class="{ active: reviewForm.rating >= star }"
|
||
@click="reviewForm.rating = star"
|
||
>★</text>
|
||
</view>
|
||
<textarea
|
||
class="review-input"
|
||
v-model="reviewForm.content"
|
||
placeholder="请输入评价内容(选填)"
|
||
maxlength="200"
|
||
></textarea>
|
||
<view class="modal-actions">
|
||
<button class="modal-btn cancel" @click="showReviewModal = false">取消</button>
|
||
<button class="modal-btn confirm" @click="submitReviewAction" :loading="reviewSubmitting">提交</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { getOrderDetail, cancelOrder, submitReview, confirmOrder, rejectOrder } from '../../utils/api'
|
||
import { useUserStore } from '../../stores/user'
|
||
import { initIM, sendCustomMessage } from '../../utils/im'
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
orderId: null,
|
||
order: {},
|
||
foodItems: [],
|
||
appeals: [],
|
||
// 评价弹窗
|
||
showReviewModal: false,
|
||
reviewForm: { rating: 5, content: '' },
|
||
reviewSubmitting: false,
|
||
statusBarHeight: 0
|
||
}
|
||
},
|
||
computed: {
|
||
/** 当前用户是否为单主 */
|
||
isOwner() {
|
||
const userStore = useUserStore()
|
||
return this.order.ownerId === userStore.userId
|
||
},
|
||
/** 按门店分组美食街菜品 */
|
||
groupedFoodItems() {
|
||
const groups = {}
|
||
this.foodItems.forEach(item => {
|
||
const key = item.shopId || item.shopName || '未知门店'
|
||
if (!groups[key]) {
|
||
groups[key] = { shopName: item.shopName || '未知门店', items: [] }
|
||
}
|
||
groups[key].items.push(item)
|
||
})
|
||
return Object.values(groups)
|
||
},
|
||
/** 总份数 */
|
||
totalQuantity() {
|
||
return this.foodItems.reduce((sum, item) => sum + (item.quantity || 0), 0)
|
||
}
|
||
},
|
||
onLoad(options) {
|
||
const sysInfo = uni.getSystemInfoSync()
|
||
this.statusBarHeight = sysInfo.statusBarHeight || 0
|
||
this.orderId = options.id
|
||
this.loadDetail()
|
||
},
|
||
onShow() {
|
||
// 每次页面显示时刷新订单数据,确保状态同步
|
||
if (this.orderId) this.loadDetail()
|
||
},
|
||
methods: {
|
||
goBack() { uni.navigateBack() },
|
||
/** 加载订单详情 */
|
||
async loadDetail() {
|
||
if (!this.orderId) return
|
||
try {
|
||
const res = await getOrderDetail(this.orderId)
|
||
this.order = res || {}
|
||
this.foodItems = res?.foodItems || []
|
||
this.appeals = res?.appeals || []
|
||
// 设置页面标题
|
||
uni.setNavigationBarTitle({
|
||
title: `我的${this.getTypeLabel(this.order.orderType)}订单详情`
|
||
})
|
||
} catch (e) {
|
||
uni.showToast({ title: '加载失败', icon: 'none' })
|
||
}
|
||
},
|
||
|
||
getTypeLabel(type) {
|
||
const map = { Pickup: '代取', Delivery: '代送', Help: '万能帮', Purchase: '代购', Food: '美食街' }
|
||
return map[type] || ''
|
||
},
|
||
|
||
getStatusLabel(status) {
|
||
const map = {
|
||
Unpaid: '待支付', Pending: '待接单', InProgress: '进行中', WaitConfirm: '待确认',
|
||
Completed: '已完成', Cancelled: '已取消', Appealing: '申诉中'
|
||
}
|
||
return map[status] || status
|
||
},
|
||
|
||
getStatusClass(status) {
|
||
const map = {
|
||
Pending: 'status-pending', InProgress: 'status-progress',
|
||
WaitConfirm: 'status-confirm', Completed: 'status-done',
|
||
Cancelled: 'status-cancel', Appealing: 'status-appeal'
|
||
}
|
||
return map[status] || ''
|
||
},
|
||
|
||
formatTime(dateStr) {
|
||
if (!dateStr) return '-'
|
||
const d = new Date(typeof dateStr === 'string' && !dateStr.endsWith('Z') ? dateStr + 'Z' : dateStr)
|
||
const pad = (n) => String(n).padStart(2, '0')
|
||
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`
|
||
},
|
||
|
||
previewImage(url) {
|
||
if (!url) return
|
||
uni.previewImage({ urls: [url] })
|
||
},
|
||
|
||
/** 取消订单 */
|
||
onCancelOrder() {
|
||
uni.showModal({
|
||
title: '取消订单',
|
||
content: '确定取消该订单?',
|
||
success: async (res) => {
|
||
if (!res.confirm) return
|
||
try {
|
||
await cancelOrder(this.orderId)
|
||
uni.showToast({ title: '订单已取消', icon: 'success' })
|
||
this.loadDetail()
|
||
} catch (e) {
|
||
// 错误已在 request 中处理
|
||
}
|
||
}
|
||
})
|
||
},
|
||
|
||
/** 跳转聊天页(如果上一页就是聊天页,直接返回) */
|
||
goChat() {
|
||
const pages = getCurrentPages()
|
||
if (pages.length >= 2) {
|
||
const prevPage = pages[pages.length - 2]
|
||
if (prevPage.route === 'pages/message/chat') {
|
||
uni.navigateBack()
|
||
return
|
||
}
|
||
}
|
||
uni.navigateTo({ url: `/pages/message/chat?orderId=${this.orderId}` })
|
||
},
|
||
|
||
/** 跳转完成订单页(跑腿提交完成凭证) */
|
||
goCompleteOrder() {
|
||
uni.navigateTo({ url: `/pages/order/complete-order?id=${this.orderId}` })
|
||
},
|
||
|
||
/** 单主确认订单完成 */
|
||
onConfirmComplete() {
|
||
uni.showModal({
|
||
title: '确认完成',
|
||
content: '确认该订单已完成?',
|
||
success: async (res) => {
|
||
if (!res.confirm) return
|
||
try {
|
||
await confirmOrder(this.orderId)
|
||
uni.showToast({ title: '订单已完成', icon: 'success' })
|
||
// 通知跑腿
|
||
try {
|
||
await initIM()
|
||
const groupId = this.order.imGroupId || `order_${this.orderId}`
|
||
await sendCustomMessage(groupId, {
|
||
bizType: 'order-status',
|
||
description: '订单已完成'
|
||
})
|
||
} catch (ex) {}
|
||
this.loadDetail()
|
||
} catch (e) {}
|
||
}
|
||
})
|
||
},
|
||
|
||
/** 单主拒绝订单完成 */
|
||
onRejectComplete() {
|
||
uni.showModal({
|
||
title: '拒绝完成',
|
||
content: '确认该订单未完成?订单将继续进行。',
|
||
success: async (res) => {
|
||
if (!res.confirm) return
|
||
try {
|
||
await rejectOrder(this.orderId)
|
||
uni.showToast({ title: '已拒绝,订单继续进行', icon: 'none' })
|
||
// 通知跑腿
|
||
try {
|
||
await initIM()
|
||
const groupId2 = this.order.imGroupId || `order_${this.orderId}`
|
||
await sendCustomMessage(groupId2, {
|
||
bizType: 'order-status',
|
||
description: '单主已拒绝完成,订单继续进行'
|
||
})
|
||
} catch (ex) {}
|
||
this.loadDetail()
|
||
} catch (e) {}
|
||
}
|
||
})
|
||
},
|
||
|
||
/** 打开评价弹窗 */
|
||
openReview() {
|
||
this.reviewForm = { rating: 5, content: '' }
|
||
this.showReviewModal = true
|
||
},
|
||
|
||
/** 提交评价 */
|
||
async submitReviewAction() {
|
||
if (this.reviewForm.rating < 1) {
|
||
uni.showToast({ title: '请选择评分', icon: 'none' })
|
||
return
|
||
}
|
||
this.reviewSubmitting = true
|
||
try {
|
||
await submitReview(this.orderId, {
|
||
rating: this.reviewForm.rating,
|
||
content: this.reviewForm.content
|
||
})
|
||
uni.showToast({ title: '评价成功', icon: 'success' })
|
||
this.showReviewModal = false
|
||
this.loadDetail()
|
||
} catch (e) {
|
||
// 错误已在 request 中处理
|
||
} finally {
|
||
this.reviewSubmitting = false
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
/* 自定义导航栏 */
|
||
.custom-navbar {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
z-index: 999;
|
||
background: #FFB700;
|
||
}
|
||
.navbar-content {
|
||
height: 44px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 0 20rpx;
|
||
}
|
||
.nav-back {
|
||
width: 60rpx;
|
||
height: 60rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.back-icon {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
}
|
||
.navbar-title {
|
||
font-size: 34rpx;
|
||
font-weight: bold;
|
||
color: #363636;
|
||
}
|
||
.nav-placeholder {
|
||
width: 60rpx;
|
||
}
|
||
.detail-page {
|
||
min-height: 100vh;
|
||
background-color: #f5f5f5;
|
||
padding: 0 0 160rpx;
|
||
}
|
||
|
||
/* 页面标题 */
|
||
.page-title {
|
||
background-color: #ffffff;
|
||
padding: 24rpx 30rpx;
|
||
}
|
||
|
||
.page-title text {
|
||
font-size: 32rpx;
|
||
color: #333333;
|
||
font-weight: bold;
|
||
}
|
||
|
||
/* 状态栏 */
|
||
.status-bar {
|
||
padding: 20rpx 30rpx;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.status-bar.status-pending { background-color: #fff7e6; }
|
||
.status-bar.status-progress { background-color: #e6f7ff; }
|
||
.status-bar.status-confirm { background-color: #fff2e8; }
|
||
.status-bar.status-done { background-color: #f6ffed; }
|
||
.status-bar.status-cancel { background-color: #f5f5f5; }
|
||
.status-bar.status-appeal { background-color: #fff1f0; }
|
||
|
||
.status-text {
|
||
font-size: 30rpx;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.status-pending .status-text { color: #faad14; }
|
||
.status-progress .status-text { color: #FFB700; }
|
||
.status-confirm .status-text { color: #ff9900; }
|
||
.status-done .status-text { color: #52c41a; }
|
||
.status-cancel .status-text { color: #999999; }
|
||
.status-appeal .status-text { color: #e64340; }
|
||
|
||
/* 信息区域 */
|
||
.info-section {
|
||
background-color: #ffffff;
|
||
margin: 0 24rpx 16rpx;
|
||
border-radius: 16rpx;
|
||
padding: 24rpx 30rpx;
|
||
}
|
||
|
||
.section-title {
|
||
padding-bottom: 16rpx;
|
||
border-bottom: 1rpx solid #f0f0f0;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.section-title text {
|
||
font-size: 30rpx;
|
||
color: #333333;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.info-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
padding: 10rpx 0;
|
||
}
|
||
|
||
.info-label {
|
||
font-size: 26rpx;
|
||
color: #999999;
|
||
flex-shrink: 0;
|
||
margin-right: 20rpx;
|
||
}
|
||
|
||
.info-value {
|
||
font-size: 26rpx;
|
||
color: #333333;
|
||
text-align: right;
|
||
flex: 1;
|
||
}
|
||
|
||
.info-value.price {
|
||
color: #e64340;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.info-value.highlight {
|
||
color: #52c41a;
|
||
font-weight: bold;
|
||
}
|
||
|
||
/* 完成凭证 */
|
||
.proof-image {
|
||
width: 100%;
|
||
max-height: 400rpx;
|
||
border-radius: 8rpx;
|
||
}
|
||
|
||
/* 美食街门店分组 */
|
||
.shop-group {
|
||
margin: 16rpx 0;
|
||
padding: 16rpx;
|
||
background-color: #fafafa;
|
||
border-radius: 12rpx;
|
||
}
|
||
|
||
.shop-name {
|
||
font-size: 28rpx;
|
||
color: #333333;
|
||
font-weight: 500;
|
||
display: block;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
|
||
.dish-item {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 10rpx 0;
|
||
}
|
||
|
||
.dish-photo {
|
||
width: 80rpx;
|
||
height: 80rpx;
|
||
border-radius: 8rpx;
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
.dish-info {
|
||
flex: 1;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.dish-name {
|
||
font-size: 26rpx;
|
||
color: #333333;
|
||
}
|
||
|
||
.dish-price {
|
||
font-size: 24rpx;
|
||
color: #e64340;
|
||
}
|
||
|
||
/* 申诉处理结果 */
|
||
.appeal-item {
|
||
padding: 16rpx 0;
|
||
border-bottom: 1rpx solid #f0f0f0;
|
||
}
|
||
|
||
.appeal-item:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.appeal-result {
|
||
font-size: 26rpx;
|
||
color: #333333;
|
||
display: block;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.appeal-time {
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
}
|
||
|
||
/* 底部操作按钮 */
|
||
.bottom-actions {
|
||
position: fixed;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
display: flex;
|
||
gap: 20rpx;
|
||
padding: 24rpx 30rpx;
|
||
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
|
||
background-color: #ffffff;
|
||
box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.06);
|
||
}
|
||
|
||
.action-btn {
|
||
flex: 1;
|
||
text-align: center;
|
||
padding: 24rpx 0;
|
||
border-radius: 12rpx;
|
||
font-size: 30rpx;
|
||
}
|
||
|
||
.btn-primary {
|
||
background-color: #FAD146;
|
||
}
|
||
|
||
.btn-primary text {
|
||
color: #333333;
|
||
}
|
||
|
||
.btn-secondary {
|
||
border: 1rpx solid #FAD146;
|
||
}
|
||
|
||
.btn-secondary text {
|
||
color: #333333;
|
||
}
|
||
|
||
.btn-cancel {
|
||
border: 1rpx solid #e64340;
|
||
}
|
||
|
||
.btn-cancel text {
|
||
color: #e64340;
|
||
}
|
||
|
||
/* 评价弹窗 */
|
||
.modal-mask {
|
||
position: fixed;
|
||
top: 0; left: 0; right: 0; bottom: 0;
|
||
background-color: rgba(0, 0, 0, 0.5);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
z-index: 999;
|
||
}
|
||
|
||
.modal-content {
|
||
width: 600rpx;
|
||
background-color: #ffffff;
|
||
border-radius: 20rpx;
|
||
padding: 40rpx;
|
||
}
|
||
|
||
.modal-title {
|
||
font-size: 34rpx;
|
||
font-weight: bold;
|
||
color: #333333;
|
||
text-align: center;
|
||
display: block;
|
||
margin-bottom: 30rpx;
|
||
}
|
||
|
||
.star-row {
|
||
display: flex;
|
||
justify-content: center;
|
||
gap: 16rpx;
|
||
margin-bottom: 30rpx;
|
||
}
|
||
|
||
.star {
|
||
font-size: 48rpx;
|
||
color: #dddddd;
|
||
}
|
||
|
||
.star.active {
|
||
color: #faad14;
|
||
}
|
||
|
||
.review-input {
|
||
width: 100%;
|
||
height: 160rpx;
|
||
border: 1rpx solid #e0e0e0;
|
||
border-radius: 12rpx;
|
||
padding: 16rpx;
|
||
font-size: 28rpx;
|
||
box-sizing: border-box;
|
||
margin-bottom: 30rpx;
|
||
}
|
||
|
||
.modal-actions {
|
||
display: flex;
|
||
gap: 20rpx;
|
||
}
|
||
|
||
.modal-btn {
|
||
flex: 1;
|
||
height: 80rpx;
|
||
line-height: 80rpx;
|
||
font-size: 30rpx;
|
||
border-radius: 40rpx;
|
||
border: none;
|
||
}
|
||
|
||
.modal-btn::after {
|
||
border: none;
|
||
}
|
||
|
||
.modal-btn.cancel {
|
||
background-color: #f5f5f5;
|
||
color: #666666;
|
||
}
|
||
|
||
.modal-btn.confirm {
|
||
background-color: #FAD146;
|
||
color: #ffffff;
|
||
}
|
||
</style>
|