feat: 订单详情布局功能调整

This commit is contained in:
duanshuwen
2025-10-29 21:08:35 +08:00
parent 89cf4f81cd
commit 2b9afb936e
23 changed files with 221 additions and 726 deletions

View File

@@ -21,17 +21,16 @@
}"
>
<view class="flex flex-items-center flex-row flex-shrink-0 mr-8">
<uni-icons fontFamily="znicons" size="20" color="#333">{{
zniconsMap[moduleItem.moduleIcon]
}}</uni-icons>
<text class="font-size-14 color-171717 line-height-20">{{
moduleItem.moduleTitle
}}</text>
<uni-icons fontFamily="znicons" size="20" color="#333">
{{ zniconsMap[moduleItem.moduleIcon] }}
</uni-icons>
<text class="font-size-14 color-171717 line-height-20">
{{ moduleItem.moduleTitle }}
</text>
</view>
<text
class="flex-full font-size-12 color-525866 line-height-20 mt-4"
>{{ moduleItem.moduleContent }}</text
>
<text class="flex-full font-size-12 color-525866 line-height-20 mt-4">
{{ moduleItem.moduleContent }}
</text>
</view>
</view>
</view>

View File

@@ -66,7 +66,7 @@ const props = defineProps({
default: true,
},
// 背景颜色
backgroundColor: {
background: {
type: String,
default: "#d9eeff",
},
@@ -131,7 +131,7 @@ const navBarClass = computed(() => {
// 计算导航栏样式
const navBarStyle = computed(() => {
return {
backgroundColor: props.backgroundColor,
background: props.background,
zIndex: props.zIndex,
};
});

View File

@@ -0,0 +1,80 @@
<template>
<view
class="footer bg-white border-box flex flex-items-center flex-justify-between p-12"
>
<button
v-if="shouldShowButton"
class="left border-none border-box bg-white rounded-10 flex flex-items-center flex-justify-center font-size-14 font-500 color-525866 mr-12"
>
取消订单
</button>
<button
:class="[
'right border-none rounded-10 flex flex-full flex-items-center flex-justify-center font-size-14 font-500',
{
'bg-FF3D60 color-white': statusCode === '0',
'bg-color-f5f7fa color-525866': statusCode === '2',
},
]"
>
{{ buttonText }}
</button>
</view>
</template>
<script setup>
import { defineProps, computed, ref, defineEmits } from "vue";
const props = defineProps({
orderData: {
type: Object,
required: true,
default: () => ({
orderId: "",
paySerialNumber: "",
payWay: "", // 支付方式 0-微信 1-支付宝 2-云闪付
payAmt: "",
orderStatus: "0", // 订单状态 0-待支付 1-待确认 2-待使用 3-已取消 4-退款中 5-已关闭 6-已完成
orderType: "0", // 0-酒店订单, 1-门票订单, 2-餐饮
}),
},
});
const statusCode = computed(() => props.orderData.orderStatus);
// 按钮文案逻辑,订单状态 0-待支付 1-待确认 2-待使用 3-已取消 4-退款中 5-已关闭 6-已完成
const buttonText = computed(() => {
switch (statusCode.value) {
case "0": // 待支付状态
return "立即支付";
case "2": // 待使用状态
return "申请退款";
case "3": // 已取消状态
case "5": // 已关闭状态
case "6": // 已完成状态
return "再次预定";
}
});
// 是否显示按钮(待支付、待使用、已取消、已关闭、已完成)
const shouldShowButton = computed(() => {
return ["0", "2", "3", "5", "6"].includes(statusCode.value);
});
</script>
<style lang="scss" scoped>
.footer {
border-radius: 12px 12px 0 0;
padding-bottom: 88rpx;
}
.left,
.right {
height: 48px;
}
.left {
border: 1px solid #e5e8ee;
width: 104px;
}
</style>

View File

@@ -1,41 +1,28 @@
<template>
<view class="goods-info mb-12">
<view class="hotel-header">
<image class="hotel-icon" :src="orderTypeIcon"></image>
<text class="hotel-name">{{ orderData.storeName }}</text>
<view class="border-box bg-white p-12 rounded-12 mb-12">
<!-- 酒店类型入住离店日期部分 -->
<DateRangeSection
v-if="orderData.commodityTypeCode === '0'"
:selectedDate="selectedDate"
/>
<view class="font-size-16 font-500 color-000 line-height-24 ellipsis-1">
{{ orderData.commodityName }}
</view>
<view class="goods-detail">
<image
v-if="shouldShowImage"
class="goods-image"
:src="commodityCoverPhoto"
lazy-load
></image>
<view class="goods-description">
<text class="goods-title">{{ commodityName }}</text>
<!-- 门店地址 -->
<LocationInfo :orderData="orderData" />
<!-- 酒店类型 -->
<template v-if="orderData.orderType === '0'">
<view class="in-date" v-if="checkInData">
入住时间{{ checkInData }}
</view>
<view class="out-date" v-if="checkOutData">
离店时间{{ checkOutData }}
</view>
</template>
<view class="border-box border-bottom">
<view class="font-size-12 color-99A0AE line-height-16 pb-12">
{{ orderData.commodityDescription }}
</view>
</view>
<view class="included-services" v-if="hasServices">
<text class="services-title">包含服务</text>
<view
v-for="item in formattedServiceList"
:key="item.key"
class="service-item"
>
<text class="service-name"> · {{ item.displayTitle }} </text>
<text class="service-quantity">
{{ item.displayAmount }}
<!-- 权益部分 -->
<view class="flex flex-items-center mb-8">
<text
class="bg-F7F7F7 border-box rounded-4 font-size-11 color-525866 mr-4 pt-4 pb-4 pl-6 pr-6"
v-for="(item, index) in orderData.commodityFacilityList"
:key="index"
>
{{ item }}
</text>
</view>
</view>
@@ -44,82 +31,29 @@
<script setup>
import { defineProps, computed } from "vue";
import LocationInfo from "@/components/LocationInfo/index.vue";
import iconHouse from "./images/icon_house.png";
import iconFood from "./images/food.png";
import iconTicket from "./images/ticket.png";
import DateRangeSection from "@/components/DateRangeSection/index.vue";
const props = defineProps({
orderData: {
type: Object,
required: true,
default: () => ({
id: "",
commodityServiceList: [],
orderStatus: "0", // 订单状态 0-待支付 1-待确认 2-待使用 3-已取消 4-退款中 5-已退款 6-已完成
orderType: "0", // 0-酒店订单, 1-门票订单, 2-餐饮
}),
default: () => ({}),
},
});
// 计算属性:商品名称
const commodityName = computed(() => {
return props.orderData.commodityName || "未知商品";
const selectedDate = computed(() => {
// 计算总天数
const startDate = props.orderData.checkInData || "";
const endDate = props.orderData.checkOutData || "";
const timeStamp = 1000 * 60 * 60 * 24;
const totalDays = (new Date(endDate) - new Date(startDate)) / timeStamp;
return {
startDate,
endDate,
totalDays,
};
});
// 计算属性:商品封面图片
const commodityCoverPhoto = computed(() => {
return props.orderData.commodityCoverPhoto || "";
});
// 计算属性:入住时间
const checkInData = computed(() => props.orderData.checkInData || "");
// 计算属性:离店时间
const checkOutData = computed(() => props.orderData.checkOutData || "");
// 计算属性:服务列表
const serviceList = computed(() => props.orderData.commodityServiceList || []);
// 计算属性:是否有服务
const hasServices = computed(() => serviceList.value.length);
// 计算属性:格式化的服务列表(预处理数据,减少模板中的计算)
const formattedServiceList = computed(() => {
return serviceList.value.map((item, index) => ({
...item,
key: item.id || item.serviceTitle || `service-${index}`,
displayTitle: item.serviceTitle || "未知服务",
displayAmount: formatServiceAmount(item.serviceAmount),
}));
});
// 计算属性:是否显示商品图片
const shouldShowImage = computed(() => {
return !!commodityCoverPhoto.value;
});
// 计算属性:根据订单类型动态显示图标
const orderTypeIcon = computed(() => {
const orderType = props.orderData.orderType;
switch (orderType) {
case "0":
return iconHouse; // 酒店订单
case "1":
return iconTicket; // 门票订单
case "2":
return iconFood; // 餐饮订单
default:
return iconHouse; // 默认显示酒店图标
}
});
// 格式化服务数量
const formatServiceAmount = (amount) => {
if (!amount) return "";
return typeof amount === "number" ? `×${amount}` : amount;
};
</script>
<style scoped lang="scss">

View File

@@ -1,14 +0,0 @@
## 商品信息组件
组件名称:商品信息组件
## 提示词:
使用 uniapp + vue3 组合式 api 开发微信小程序,要求如下:
1、按照提供的图片高度还原交互设计
2、要求布局样式结构简洁明了class 命名请按照模块名称来命名,例如:.goods-info
3、可以使用 uniapp 内置的组件
## 备注
仅供学习、交流使用,请勿用于商业用途。

View File

@@ -1,141 +0,0 @@
// ===== SASS变量定义 =====
// 颜色系统
$color-white: #fff;
$color-primary: #333;
$color-secondary: #666;
$color-placeholder: pink;
// 字体大小
$font-size-xs: 12px;
$font-size-sm: 14px;
$font-size-base: 16px;
// 字体粗细
$font-weight-normal: 400;
$font-weight-medium: 500;
$font-weight-bold: 600;
// 间距系统
$spacing-xs: 8px;
$spacing-sm: 10px;
$spacing-md: 12px;
$spacing-lg: 15px;
$spacing-xl: 16px;
$spacing-xxl: 20px;
// 圆角
$border-radius-sm: 8px;
$border-radius-md: 10px;
// 尺寸
$icon-size-sm: 24px;
$image-size-md: 65px;
// ===== SASS混合器 =====
@mixin flex-center {
display: flex;
align-items: center;
}
@mixin flex-between {
display: flex;
justify-content: space-between;
}
@mixin text-style($size, $color: $color-primary, $weight: $font-weight-normal) {
font-size: $size;
color: $color;
font-weight: $weight;
}
@mixin card-container {
background-color: $color-white;
border-radius: $border-radius-md;
padding: $spacing-md $spacing-xl $spacing-xxl;
}
// ===== 主要样式 =====
.goods-info {
@include card-container;
// 酒店头部信息
.hotel-header {
@include flex-center;
margin-bottom: $spacing-sm;
.hotel-icon {
width: $icon-size-sm;
height: $icon-size-sm;
margin-right: $spacing-xs;
}
.hotel-name {
@include text-style($font-size-xs, $color-primary, $font-weight-medium);
}
}
// 商品详情区域
.goods-detail {
display: flex;
margin-bottom: $spacing-xxl;
.goods-image {
background-color: $color-placeholder;
width: $image-size-md;
height: $image-size-md;
border-radius: $border-radius-sm;
margin-right: $spacing-lg;
flex-shrink: 0;
}
.goods-description {
flex: 1;
min-width: 0; // 防止flex子项溢出
.goods-title {
display: block;
@include text-style($font-size-sm, $color-primary, $font-weight-medium);
margin-bottom: $spacing-xs;
line-height: 1.4;
}
.in-date,
.out-date {
@include text-style($font-size-xs, $color-secondary);
margin-top: 8px;
}
}
}
// 包含服务区域
.included-services {
margin-top: $spacing-sm;
.services-title {
display: block;
@include text-style($font-size-xs, $color-primary, $font-weight-medium);
margin-bottom: $spacing-md;
}
.service-item {
@include flex-between;
align-items: center;
margin-bottom: $spacing-sm;
&:last-child {
margin-bottom: 0;
}
.service-name {
@include text-style($font-size-sm, $color-primary);
flex: 1;
}
.service-quantity {
@include text-style($font-size-xs, $color-secondary);
flex-shrink: 0;
margin-left: $spacing-xs;
}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -1,38 +1,25 @@
<template>
<view class="order-info">
<view class="order-item">
<text class="label">订单号</text>
<text class="value">{{ orderData.orderId }}</text>
<view class="bg-white border-box rounded-10 p-12">
<view class="flex mb-8 font-size-12">
<text class="w-60 color-99A0AE">订单</text>
<text class="color-525866">{{ orderData.orderId }}</text>
</view>
<view class="order-item">
<text class="label">流水号</text>
<text class="value">{{ orderData.paySerialNumber }}</text>
<view class="flex mb-8 font-size-12">
<text class="w-60 color-99A0AE">下单时间</text>
<text class="color-525866">{{ orderData.createTime }}</text>
</view>
<view class="order-item">
<text class="label">支付方式</text>
<text class="value">{{ payWayText }}</text>
</view>
<!-- 在已退款状态显示 -->
<view v-if="orderData.orderStatus === '4'" class="order-item">
<text class="label">退款单号</text>
<text class="value">{{ orderData.refundOrderNo }}</text>
</view>
<view class="line"></view>
<view class="order-item amount">
<text class="label">实际支付金额</text>
<text class="value">{{ formattedAmount }}</text>
</view>
<!-- 根据订单状态动态显示按钮 -->
<button
v-if="shouldShowButton"
:class="['reserve-button', { loading: isLoading }]"
:disabled="isLoading"
@click="handleButtonClick(orderData)"
>
{{ isLoading ? "处理中..." : buttonText }}
</button>
<view class="feedback">
<text @click="openFeedback">投诉反馈</text>
<view class="flex font-size-12">
<text class="w-60 color-99A0AE">支付状态</text>
<text
:class="[
{
'color-FF3D60': statusCode === '0',
'color-21B466': statusCode === '1',
},
]"
>
{{ payStatusText }}
</text>
</view>
</view>
</template>
@@ -42,10 +29,9 @@ import { defineProps, computed, ref, defineEmits } from "vue";
import { orderPayNow } from "@/request/api/OrderApi";
// 支付方式映射常量
const PAY_WAY_MAP = {
0: "微信",
1: "支付",
2: "云闪付",
const PAY_STATUS_MAP = {
0: "未支付",
1: "支付",
};
// 加载状态
@@ -68,11 +54,10 @@ const props = defineProps({
}),
},
});
const statusCode = computed(() => props.orderData.orderStatus);
// 使用计算属性缓存支付方式文本
const payWayText = computed(() => {
return PAY_WAY_MAP[props.orderData.payWay] || "未知支付方式";
});
const payStatusText = computed(() => PAY_STATUS_MAP[statusCode.value]);
// 格式化金额显示
const formattedAmount = computed(() => {
@@ -80,27 +65,6 @@ const formattedAmount = computed(() => {
return amount ? `${parseFloat(amount).toFixed(2)}` : "0.00";
});
// 按钮文案逻辑,订单状态 0-待支付 1-待确认 2-待使用 3-已取消 4-退款中 5-已关闭 6-已完成
const buttonText = computed(() => {
const status = props.orderData.orderStatus;
switch (status) {
case "0": // 待支付状态
return "立即支付";
case "2": // 待使用状态
return "申请退款";
case "3": // 已取消状态
case "5": // 已关闭状态
case "6": // 已完成状态
return "再次预定";
}
});
// 是否显示按钮(待支付、待使用、已取消、已关闭、已完成)
const shouldShowButton = computed(() => {
const status = props.orderData.orderStatus;
return ["0", "2", "3", "5", "6"].includes(status);
});
// 处理按钮点击事件
const handleButtonClick = async (orderData) => {
if (isLoading.value) return; // 防止重复点击
@@ -195,14 +159,6 @@ const handleButtonClick = async (orderData) => {
isLoading.value = false;
}
};
// 投诉电话
const openFeedback = () => {
const phoneNumber = props.orderData.complaintHotline;
uni.makePhoneCall({ phoneNumber });
};
</script>
<style scoped lang="scss">
@import "./styles/index.scss";
</style>
<style scoped lang="scss"></style>

View File

@@ -1,14 +0,0 @@
## 订单信息组件
组件名称:订单信息组件
## 提示词:
使用 uniapp + vue3 组合式 api 开发微信小程序,要求如下:
1、按照提供的图片高度还原交互设计
2、要求布局样式结构简洁明了class 命名请按照模块名称来命名,例如:.order-info
3、可以使用 uniapp 内置的组件
## 备注
仅供学习、交流使用,请勿用于商业用途。

View File

@@ -1,156 +0,0 @@
// 颜色系统
$order-bg-color: #fff;
$text-color-primary: #333;
$text-color-secondary: #666;
$text-color-accent: #ff5722;
$button-color: #00a6ff;
$button-disabled-color: #ccc;
$border-color: #ececec;
$shadow-color: rgba(0, 0, 0, 0.08);
// 尺寸和间距
$order-border-radius: 10px;
$order-padding: 16px 18px;
$spacing-small: 8px;
$spacing-medium: 10px;
$spacing-large: 20px;
$button-height: 42px;
// 字体系统
$font-size-small: 12px;
$font-size-medium: 14px;
$font-size-large: 18px;
$font-weight-normal: 400;
$font-weight-medium: 500;
$font-weight-semibold: 600;
// 过渡动画
$transition-fast: 0.2s ease;
$transition-normal: 0.3s ease;
.order-info {
background-color: $order-bg-color;
border-radius: $order-border-radius;
padding: $order-padding;
box-shadow: 0 2px 8px $shadow-color;
transition: box-shadow $transition-normal;
&:hover {
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
}
// 订单项样式,优化布局和视觉层次
.order-item {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: $spacing-small;
padding: 4px 0;
transition: background-color $transition-fast;
.label {
font-size: $font-size-small;
color: $text-color-secondary;
font-weight: $font-weight-normal;
flex-shrink: 0;
line-height: 1.4;
}
.value {
font-size: $font-size-small;
color: $text-color-primary;
font-weight: $font-weight-normal;
text-align: right;
word-break: break-word;
overflow-wrap: break-word;
line-height: 1.4;
max-width: 60%;
}
// 金额特殊样式,增强视觉重点
&.amount {
.label {
color: $text-color-primary;
font-weight: $font-weight-medium;
font-size: $font-size-medium;
}
.value {
color: $text-color-accent;
font-size: $font-size-large;
font-weight: $font-weight-semibold;
max-width: none;
// 货币符号样式
&::before {
content: "¥";
margin-right: 2px;
font-size: 11px;
}
}
}
}
.line {
border-bottom: 1px solid $border-color;
margin: $spacing-medium 0;
height: 0;
opacity: 0.6;
transition: opacity $transition-fast;
&:hover {
opacity: 1;
}
}
.reserve-button {
width: 100%;
background: linear-gradient(179deg, #00a6ff 0%, #0256ff 100%);
color: #fff;
border: none;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
border-radius: $uni-border-radius-50px;
height: $button-height;
font-size: $font-size-medium;
font-weight: $font-weight-medium;
margin-top: $spacing-large;
position: relative;
overflow: hidden;
letter-spacing: 0.5px;
&:disabled {
background: $button-disabled-color;
cursor: not-allowed;
transform: none;
box-shadow: none;
&::before {
display: none;
}
}
// 加载状态样式
&.loading {
background: $button-disabled-color;
cursor: not-allowed;
transform: none;
box-shadow: none;
position: relative;
&::before {
display: none;
}
}
}
.feedback {
text-align: center;
font-size: $font-size-medium;
color: $text-color-primary;
font-weight: $font-weight-normal;
margin-top: $spacing-medium;
}
}

View File

@@ -1,5 +1,7 @@
<template>
<view class="order-qrcode">
<view
class="bg-white border-box rounded-12 flex flex-items-center flex-justify-center p-20 mb-12"
>
<Qrcode
:size="size"
:unit="unit"
@@ -30,6 +32,4 @@ const props = defineProps({
});
</script>
<style scoped lang="scss">
@import "./styles/index.scss";
</style>
<style scoped lang="scss"></style>

View File

@@ -1,18 +0,0 @@
.order-qrcode {
background-color: $uni-bg-color;
border-radius: 10px;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 18px;
margin-bottom: 12px;
text {
font-size: $uni-font-size-sm;
color: #666666;
line-height: 17px;
margin-top: 4px;
}
}

View File

@@ -2,7 +2,7 @@
<view
class="border-box font-size-24 color-171717 line-height-32 font-500 pt-12 pb-12"
>
{{ statusText }}
{{ currentStatusText }}
</view>
</template>
@@ -11,34 +11,13 @@ import { defineProps, computed } from "vue";
// 订单状态配置映射
const ORDER_STATUS_CONFIG = {
0: {
text: "待支付",
description: "请尽快完成支付",
},
1: {
text: "待确认",
description: "商家正在确认您的订单",
},
2: {
text: "待使用",
description: "预订成功,订单待使用",
},
3: {
text: "已取消",
description: "订单已取消",
},
4: {
text: "退款中",
description: "商家退款正在处理中,请耐心等待",
},
5: {
text: "已退款",
description: "款项预计1-7个工作日退回至原支付账户",
},
6: {
text: "已完成",
description: "订单已完成,感谢您的使用",
},
0: "待支付",
1: "待确认",
2: "待使用",
3: "已取消",
4: "退款中",
5: "已退款",
6: "已完成",
};
const props = defineProps({
@@ -56,22 +35,12 @@ const props = defineProps({
},
});
// 当前状态配置
const currentStatusConfig = computed(() => {
// 当前状态
const currentStatusText = computed(() => {
return (
ORDER_STATUS_CONFIG[props.orderData.orderStatus] || ORDER_STATUS_CONFIG["0"]
);
});
// 状态文本
const statusText = computed(() => {
return currentStatusConfig.value.text;
});
// 状态描述
const statusDescription = computed(() => {
return currentStatusConfig.value.description;
});
</script>
<style scoped lang="scss">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

View File

@@ -1,45 +1,24 @@
<template>
<view class="user-info mb-12" v-if="hasConsumerData">
<view class="user-info-title">{{ infoTitle }}</view>
<view
v-for="(item, index) in consumerList"
:key="getConsumerKey(item, index)"
class="user-info-group"
>
<view class="user-info-item">
<text class="label">{{ contactLabel }}</text>
<text class="value">{{ item.visitorName || "未填写" }}</text>
</view>
<view class="user-info-item">
<text class="label">联系电话</text>
<text class="value">{{ formatPhone(item.contactPhone) }}</text>
<view
class="bg-white border-box rounded-10 p-12 mb-12"
v-if="hasConsumerData"
>
<view v-for="(item, index) in consumerList" :key="index">
<view class="flex mb-8 font-size-12">
<text class="w-60 color-99A0AE">住客姓名</text>
<text class="color-525866">{{ item.visitorName }}</text>
</view>
</view>
<view class="flex font-size-12">
<text class="w-60 color-99A0AE">联系电话</text>
<text class="color-525866">{{ contactPhone }}</text>
</view>
</view>
</template>
<script setup>
import { defineProps, computed } from "vue";
// 订单类型常量
const ORDER_TYPES = {
HOTEL: "0", // 酒店订单
TICKET: "1", // 门票订单
DINING: "2", // 餐饮订单
};
// 信息配置映射
const INFO_CONFIG = {
[ORDER_TYPES.HOTEL]: {
title: "订房信息",
contactLabel: "联系房客:",
},
default: {
title: "游客信息",
contactLabel: "联系游客:",
},
};
const props = defineProps({
orderData: {
type: Object,
@@ -53,44 +32,14 @@ const props = defineProps({
},
});
// 使用计算属性缓存信息标题
const infoTitle = computed(() => {
const config = INFO_CONFIG[props.orderData.orderType] || INFO_CONFIG.default;
return config.title;
});
// 使用计算属性缓存联系人标签
const contactLabel = computed(() => {
const config = INFO_CONFIG[props.orderData.orderType] || INFO_CONFIG.default;
return config.contactLabel;
});
// 使用计算属性处理用户信息列表,提供更好的响应性和缓存
const consumerList = computed(() => {
return props.orderData.consumerInfoList || [];
});
const consumerList = computed(() => props.orderData.consumerInfoList || []);
// 联系电话
const contactPhone = computed(() => consumerList.value[0]?.contactPhone);
// 检查是否有用户数据
const hasConsumerData = computed(() => {
return consumerList.value.length > 0;
});
// 生成更稳定的key值优先使用唯一标识
const getConsumerKey = (item, index) => {
return item.id || item.visitorName || `consumer-${index}`;
};
// 格式化电话号码显示
const formatPhone = (phone) => {
if (!phone) return "未填写";
// 简单的电话号码格式化,中间部分用*号隐藏
if (phone.length === 11) {
return phone.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
}
return phone;
};
const hasConsumerData = computed(() => consumerList.value.length);
</script>
<style scoped lang="scss">
@import "./styles/index.scss";
</style>
<style scoped lang="scss"></style>

View File

@@ -1,14 +0,0 @@
## 游客信息组件
组件名称:游客信息组件
## 提示词:
使用 uniapp + vue3 组合式 api 开发微信小程序,要求如下:
1、按照提供的图片高度还原交互设计
2、要求布局样式结构简洁明了class 命名请按照模块名称来命名,例如:.user-info
3、可以使用 uniapp 内置的组件
## 备注
仅供学习、交流使用,请勿用于商业用途。

View File

@@ -1,28 +0,0 @@
.user-info {
background-color: #fff;
border-radius: 10px;
padding: 16px 18px;
}
.user-info-title {
font-size: $uni-font-size-lg;
font-weight: 600;
margin-bottom: 14px;
}
.user-info-item {
display: flex;
align-items: center;
margin-bottom: 10px;
}
.label {
font-size: $uni-font-size-base;
color: #666;
margin-right: 8px;
}
.value {
font-size: $uni-font-size-base;
color: $uni-text-color;
}

View File

@@ -1,14 +1,10 @@
<template>
<view class="order-detail-page">
<TopNavBar
titleAlign="center"
:backgroundColor="backgroundColor"
:shadow="shadow"
title="订单详情"
fixed
/>
<view class="order-detail-page flex flex-col h-screen">
<TopNavBar titleAlign="center" background="#D9EEFF" title="订单详情" />
<view class="order-detail-wrapper">
<view
class="order-detail-wrapper border-box flex-full overflow-hidden scroll-y"
>
<OrderStatusInfo :orderData="orderData" />
<OrderQrcode
v-if="orderData.orderStatus === '2'"
@@ -17,27 +13,30 @@
:val="orderData.orderId"
/>
<GoodsInfo :orderData="orderData" />
<UserInfo :orderData="orderData" />
<NoticeInfo :orderData="orderData" />
<OrderInfo
:orderData="orderData"
@show-refund-popup="showRefundPopup"
@pay-success="handlePaySuccess"
/>
<!-- 退款状态显示 -->
<RefundPopup
v-model="refundVisible"
:orderData="orderData"
@confirm="handleRefundConfirm"
/>
<UserInfo :orderData="orderData" />
<OrderInfo :orderData="orderData" />
</view>
<FooterSection
:orderData="orderData"
@show-refund-popup="showRefundPopup"
@pay-success="handlePaySuccess"
/>
</view>
<!-- 退款状态显示 -->
<RefundPopup
v-model="refundVisible"
:orderData="orderData"
@confirm="handleRefundConfirm"
/>
</template>
<script setup>
import { ref } from "vue";
import { onLoad, onPageScroll } from "@dcloudio/uni-app";
import { onLoad } from "@dcloudio/uni-app";
import { userOrderDetail, orderRefund } from "@/request/api/OrderApi";
import TopNavBar from "@/components/TopNavBar/index.vue";
import OrderQrcode from "./components/OrderQrcode/index.vue";
@@ -46,6 +45,7 @@ import GoodsInfo from "./components/GoodsInfo/index.vue";
import UserInfo from "./components/UserInfo/index.vue";
import NoticeInfo from "./components/NoticeInfo/index.vue";
import OrderInfo from "./components/OrderInfo/index.vue";
import FooterSection from "./components/FooterSection/index.vue";
import RefundPopup from "@/components/RefundPopup/index.vue";
const refundVisible = ref(false);
@@ -60,22 +60,6 @@ const getOrderDetail = async (orderId) => {
console.log(res);
};
// 监听页面滚动事件
const backgroundColor = ref("transparent");
const shadow = ref(false);
onPageScroll(({ scrollTop }) => {
console.log("🚀 ~ scrollTop:", scrollTop);
// 当滚动到顶部时,显示返回按钮
if (scrollTop <= 0) {
backgroundColor.value = "transparent";
shadow.value = false;
} else {
backgroundColor.value = "#ffffff";
shadow.value = true;
}
});
// 显示退款弹窗
const showRefundPopup = () => {
refundVisible.value = true;

View File

@@ -1,4 +1,4 @@
.order-detail-wrapper {
background: linear-gradient(180deg, #d9eeff 0%, #f5f7fa 100%);
padding: 88px 15px;
padding: 0 12px 40px;
}

View File

@@ -27,6 +27,10 @@
background-color: #eef8ff;
}
.bg-FF3D60 {
background-color: #ff3d60;
}
.bg-liner {
background: linear-gradient(205deg, #8ae3fc 0%, rgba(138, 227, 252, 0) 20%),
linear-gradient(155deg, #fef7e1 0%, rgba(254, 247, 225, 0) 20%),

View File

@@ -17,4 +17,8 @@
.border-none {
border: none;
&::after {
display: none !important;
}
}

View File

@@ -1,8 +1,4 @@
// 弹性布局
.flex {
display: flex;
}
.flex-items-center {
align-items: center;
}

View File

@@ -9,6 +9,11 @@
.w-50 {
width: 50%;
}
.w-60 {
width: 60px;
}
.w-80 {
width: 80px;
}