feat: 优化订单详情滚动交互
This commit is contained in:
@@ -1,22 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="navBarClass" :style="navBarStyle">
|
<view :class="navBarClass" :style="navBarStyle">
|
||||||
<!-- 状态栏占位 -->
|
<!-- 状态栏占位 -->
|
||||||
<view :style="{ height: statusBarHeight + 'px' }" v-if="!hideStatusBar"></view>
|
<view
|
||||||
|
:style="{ height: statusBarHeight + 'px' }"
|
||||||
|
v-if="!hideStatusBar"
|
||||||
|
></view>
|
||||||
|
|
||||||
<!-- 导航栏内容 -->
|
<!-- 导航栏内容 -->
|
||||||
<view class="nav-bar-content" :style="{ height: navBarHeight + 'px' }">
|
<view class="nav-bar-content" :style="{ height: navBarHeight + 'px' }">
|
||||||
<!-- 左侧返回按钮 -->
|
<!-- 左侧返回按钮 -->
|
||||||
<view class="nav-bar-left" @click="handleBack" v-if="showBack">
|
<view class="nav-bar-left" @click="handleBack" v-if="showBack">
|
||||||
<uni-icons type="left" size="20" :color="backIconColor" />
|
<uni-icons type="left" size="20" :color="backIconColor" />
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 中间标题区域 -->
|
<!-- 中间标题区域 -->
|
||||||
<view :class="['nav-bar-center', `nav-bar-center--${titleAlign}`]">
|
<view :class="['nav-bar-center', `nav-bar-center--${titleAlign}`]">
|
||||||
<slot name="title">
|
<slot name="title">
|
||||||
<text class="nav-bar-title" :style="{ color: titleColor }">{{ title }}</text>
|
<text class="nav-bar-title" :style="{ color: titleColor }">{{
|
||||||
|
title
|
||||||
|
}}</text>
|
||||||
</slot>
|
</slot>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 右侧操作区域 -->
|
<!-- 右侧操作区域 -->
|
||||||
<view class="nav-bar-right">
|
<view class="nav-bar-right">
|
||||||
<slot name="right"></slot>
|
<slot name="right"></slot>
|
||||||
@@ -26,108 +31,114 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, onMounted, ref } from 'vue'
|
import { computed, onMounted, ref } from "vue";
|
||||||
|
|
||||||
// 定义props
|
// 定义props
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
// 标题文本
|
// 标题文本
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: "",
|
||||||
},
|
},
|
||||||
// 是否固定在顶部
|
// 是否固定在顶部
|
||||||
fixed: {
|
fixed: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
|
},
|
||||||
|
// 是否添加阴影
|
||||||
|
shadow: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
},
|
},
|
||||||
// 是否显示返回按钮
|
// 是否显示返回按钮
|
||||||
showBack: {
|
showBack: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true,
|
||||||
},
|
},
|
||||||
// 背景颜色
|
// 背景颜色
|
||||||
backgroundColor: {
|
backgroundColor: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '#ffffff'
|
default: "#ffffff",
|
||||||
},
|
},
|
||||||
// 标题颜色
|
// 标题颜色
|
||||||
titleColor: {
|
titleColor: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '#333333'
|
default: "#333333",
|
||||||
},
|
},
|
||||||
// 返回按钮图标颜色
|
// 返回按钮图标颜色
|
||||||
backIconColor: {
|
backIconColor: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '#333333'
|
default: "#333333",
|
||||||
},
|
},
|
||||||
// 是否隐藏状态栏占位
|
// 是否隐藏状态栏占位
|
||||||
hideStatusBar: {
|
hideStatusBar: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
// 自定义z-index
|
// 自定义z-index
|
||||||
zIndex: {
|
zIndex: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 999
|
default: 999,
|
||||||
},
|
},
|
||||||
// 标题对齐方式
|
// 标题对齐方式
|
||||||
titleAlign: {
|
titleAlign: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'center', // 'center' | 'left'
|
default: "center", // 'center' | 'left'
|
||||||
validator: (value) => ['center', 'left'].includes(value)
|
validator: (value) => ["center", "left"].includes(value),
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
// 定义emits
|
// 定义emits
|
||||||
const emit = defineEmits(['back'])
|
const emit = defineEmits(["back"]);
|
||||||
|
|
||||||
// 系统信息
|
// 系统信息
|
||||||
const statusBarHeight = ref(0)
|
const statusBarHeight = ref(0);
|
||||||
const navBarHeight = ref(44) // 默认导航栏高度
|
const navBarHeight = ref(44); // 默认导航栏高度
|
||||||
|
|
||||||
// 获取系统信息
|
// 获取系统信息
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const systemInfo = uni.getSystemInfoSync()
|
const systemInfo = uni.getSystemInfoSync();
|
||||||
statusBarHeight.value = systemInfo.statusBarHeight || 0
|
statusBarHeight.value = systemInfo.statusBarHeight || 0;
|
||||||
|
|
||||||
// 根据平台设置导航栏高度
|
// 根据平台设置导航栏高度
|
||||||
if (systemInfo.platform === 'ios') {
|
if (systemInfo.platform === "ios") {
|
||||||
navBarHeight.value = 44
|
navBarHeight.value = 44;
|
||||||
} else {
|
} else {
|
||||||
navBarHeight.value = 48
|
navBarHeight.value = 48;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
// 计算导航栏样式类
|
// 计算导航栏样式类
|
||||||
const navBarClass = computed(() => {
|
const navBarClass = computed(() => {
|
||||||
return [
|
return [
|
||||||
'top-nav-bar',
|
"top-nav-bar",
|
||||||
{
|
{
|
||||||
'top-nav-bar--fixed': props.fixed
|
"top-nav-bar--fixed": props.fixed,
|
||||||
}
|
"has-shadow": props.shadow,
|
||||||
]
|
},
|
||||||
})
|
];
|
||||||
|
});
|
||||||
|
|
||||||
// 计算导航栏样式
|
// 计算导航栏样式
|
||||||
const navBarStyle = computed(() => {
|
const navBarStyle = computed(() => {
|
||||||
return {
|
return {
|
||||||
backgroundColor: props.backgroundColor,
|
backgroundColor: props.backgroundColor,
|
||||||
zIndex: props.zIndex
|
zIndex: props.zIndex,
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
|
|
||||||
// 处理返回事件
|
// 处理返回事件
|
||||||
const handleBack = () => {
|
const handleBack = () => {
|
||||||
emit('back')
|
emit("back");
|
||||||
// 如果没有监听back事件,默认执行返回上一页
|
// 如果没有监听back事件,默认执行返回上一页
|
||||||
if (!emit('back')) {
|
if (!emit("back")) {
|
||||||
uni.navigateBack({
|
uni.navigateBack({
|
||||||
delta: 1
|
delta: 1,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@use "./styles/index.scss";
|
@use "./styles/index.scss";
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -2,7 +2,10 @@
|
|||||||
.top-nav-bar {
|
.top-nav-bar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.1);
|
|
||||||
|
&.has-shadow {
|
||||||
|
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
&--fixed {
|
&--fixed {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -44,6 +47,7 @@
|
|||||||
|
|
||||||
.nav-bar-center {
|
.nav-bar-center {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
height: 30px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|||||||
@@ -134,48 +134,8 @@ $transition-normal: 0.3s ease;
|
|||||||
margin-top: $spacing-large;
|
margin-top: $spacing-large;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: all $transition-normal;
|
|
||||||
letter-spacing: 0.5px;
|
letter-spacing: 0.5px;
|
||||||
|
|
||||||
// 按钮波纹效果
|
|
||||||
&::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
background: rgba(255, 255, 255, 0.3);
|
|
||||||
border-radius: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
transition: width 0.6s, height 0.6s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: linear-gradient(
|
|
||||||
135deg,
|
|
||||||
$button-hover-color 0%,
|
|
||||||
color.scale($button-hover-color, $lightness: -11.9%) 100%
|
|
||||||
);
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 4px 16px rgba($button-color, 0.4);
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
width: 300px;
|
|
||||||
height: 300px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
transform: translateY(-1px);
|
|
||||||
box-shadow: 0 2px 8px rgba($button-color, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
outline: none;
|
|
||||||
box-shadow: 0 0 0 3px rgba($button-color, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
background: $button-disabled-color;
|
background: $button-disabled-color;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
|
|||||||
@@ -113,9 +113,9 @@ const commodityPurchaseInstruction = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 方法定义
|
// 方法定义
|
||||||
const show = () => popupRef.value.open();
|
const show = () => popupRef.value && popupRef.value.open();
|
||||||
|
|
||||||
const hide = () => popupRef.value.close();
|
const hide = () => popupRef.value && popupRef.value.close();
|
||||||
|
|
||||||
// 监听modelValue变化
|
// 监听modelValue变化
|
||||||
watch(
|
watch(
|
||||||
|
|||||||
@@ -1,32 +1,45 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="order-detail-wrapper">
|
<view class="order-detail-page">
|
||||||
<uni-icons type="left" size="20" color="#fff" @click="goBack" />
|
<TopNavBar
|
||||||
|
titleAlign="center"
|
||||||
|
:backgroundColor="backgroundColor"
|
||||||
|
:backIconColor="backIconColor"
|
||||||
|
:shadow="shadow"
|
||||||
|
fixed
|
||||||
|
>
|
||||||
|
<template #title>
|
||||||
|
{{ title }}
|
||||||
|
</template>
|
||||||
|
</TopNavBar>
|
||||||
|
|
||||||
<OrderStatusInfo :orderData="orderData" />
|
<view class="order-detail-wrapper">
|
||||||
<OrderQrcode
|
<OrderStatusInfo :orderData="orderData" />
|
||||||
v-if="orderData.orderStatus === '2'"
|
<OrderQrcode
|
||||||
size="132"
|
v-if="orderData.orderStatus === '2'"
|
||||||
unit="px"
|
size="132"
|
||||||
:val="orderData.orderId"
|
unit="px"
|
||||||
/>
|
:val="orderData.orderId"
|
||||||
<GoodsInfo :orderData="orderData" />
|
/>
|
||||||
<UserInfo :orderData="orderData" />
|
<GoodsInfo :orderData="orderData" />
|
||||||
<NoticeInfo :orderData="orderData" />
|
<UserInfo :orderData="orderData" />
|
||||||
<OrderInfo :orderData="orderData" @show-refund-popup="showRefundPopup" />
|
<NoticeInfo :orderData="orderData" />
|
||||||
|
<OrderInfo :orderData="orderData" @show-refund-popup="showRefundPopup" />
|
||||||
|
|
||||||
<!-- 退款状态显示 -->
|
<!-- 退款状态显示 -->
|
||||||
<RefundPopup
|
<RefundPopup
|
||||||
v-model="refundVisible"
|
v-model="refundVisible"
|
||||||
:orderData="orderData"
|
:orderData="orderData"
|
||||||
@confirm="handleRefundConfirm"
|
@confirm="handleRefundConfirm"
|
||||||
/>
|
/>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { onLoad } from "@dcloudio/uni-app";
|
import { onLoad, onPageScroll } from "@dcloudio/uni-app";
|
||||||
import { userOrderDetail, orderRefund } from "@/request/api/OrderApi";
|
import { userOrderDetail, orderRefund } from "@/request/api/OrderApi";
|
||||||
|
import TopNavBar from "@/components/TopNavBar/index.vue";
|
||||||
import OrderQrcode from "./components/OrderQrcode/index.vue";
|
import OrderQrcode from "./components/OrderQrcode/index.vue";
|
||||||
import OrderStatusInfo from "./components/OrderStatusInfo/index.vue";
|
import OrderStatusInfo from "./components/OrderStatusInfo/index.vue";
|
||||||
import GoodsInfo from "./components/GoodsInfo/index.vue";
|
import GoodsInfo from "./components/GoodsInfo/index.vue";
|
||||||
@@ -45,12 +58,25 @@ onLoad(async ({ orderId }) => {
|
|||||||
console.log(res);
|
console.log(res);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 返回上一页
|
// 监听页面滚动事件
|
||||||
const goBack = () => {
|
const backgroundColor = ref("transparent");
|
||||||
uni.navigateBack({
|
const backIconColor = ref("#fff");
|
||||||
delta: 1,
|
const title = ref("");
|
||||||
});
|
const shadow = ref(false);
|
||||||
};
|
onPageScroll(({ scrollTop }) => {
|
||||||
|
// 当滚动到顶部时,显示返回按钮
|
||||||
|
if (scrollTop <= 0) {
|
||||||
|
backgroundColor.value = "transparent";
|
||||||
|
backIconColor.value = "#fff";
|
||||||
|
title.value = "";
|
||||||
|
shadow.value = false;
|
||||||
|
} else {
|
||||||
|
backgroundColor.value = "#ffffff";
|
||||||
|
backIconColor.value = "#333333";
|
||||||
|
title.value = "订单详情";
|
||||||
|
shadow.value = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 显示退款弹窗
|
// 显示退款弹窗
|
||||||
const showRefundPopup = () => {
|
const showRefundPopup = () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user