feat: 调整项目结构

This commit is contained in:
duanshuwen
2025-09-21 17:25:09 +08:00
parent 0b66462d16
commit 9f23854ad5
410 changed files with 3806 additions and 1668 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -0,0 +1,166 @@
<template>
<view class="order-info">
<view class="order-item">
<text class="label">订单号</text>
<text class="value">{{ orderData.orderId }}</text>
</view>
<view class="order-item">
<text class="label">流水号</text>
<text class="value">{{ orderData.paySerialNumber }}</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"
>
{{ isLoading ? "处理中..." : buttonText }}
</button>
<view class="feedback">
<text @click="openFeedback">投诉反馈</text>
</view>
</view>
</template>
<script setup>
import { defineProps, computed, ref, defineEmits } from "vue";
import {
preOrder,
orderPayNow,
orderCancel,
orderRefund,
} from "@/request/api/OrderApi";
// 支付方式映射常量
const PAY_WAY_MAP = {
0: "微信",
1: "支付宝",
2: "云闪付",
};
// 加载状态
const isLoading = ref(false);
// 定义事件发射器
const emit = defineEmits(['show-refund-popup']);
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 payWayText = computed(() => {
return PAY_WAY_MAP[props.orderData.payWay] || "未知支付方式";
});
// 格式化金额显示
const formattedAmount = computed(() => {
const amount = props.orderData.payAmt;
return amount ? `${parseFloat(amount).toFixed(2)}` : "0.00";
});
// 按钮文案逻辑
const buttonText = computed(() => {
const status = props.orderData.orderStatus;
switch (status) {
case "0": // 待支付状态
return "立即支付";
case "2": // 待使用状态
return "申请退款";
default: // 其他状态
return "再次预定";
}
});
// 是否显示按钮(退款中状态不显示)
const shouldShowButton = computed(() => {
return props.orderData.orderStatus !== "4"; // 4-退款中
});
// 处理按钮点击事件
const handleButtonClick = async () => {
if (isLoading.value) return; // 防止重复点击
const status = props.orderData.orderStatus;
const orderId = props.orderData.orderId;
// 支付方式
const payWay = props.orderData.payWay;
// 支付渠道
const paySource = "1";
if (status === "2") {
// 情况2待使用状态显示退款弹窗
emit('show-refund-popup');
return; // 直接返回,不执行后续代码
}
try {
isLoading.value = true;
// 情况1待支付状态或其他状态先预下单再支付
// 第一步:预下单
const res = await orderPayNow({ orderId, payWay, paySource });
console.log(res);
// 仅作为示例,非真实参数信息。
uni.requestPayment({
provider: "wxpay",
timeStamp: String(Date.now()),
nonceStr: "A1B2C3D4E5",
package: "prepay_id=wx20180101abcdefg",
signType: "MD5",
paySign: "",
success: (res) => {
console.log("success:" + JSON.stringify(res));
},
fail: (err) => {
console.log("fail:" + JSON.stringify(err));
},
});
} catch (error) {
console.error("操作失败:", error);
uni.showToast({
title: error.message || "操作失败,请重试",
icon: "none",
});
} finally {
isLoading.value = false;
}
};
// 投诉电话
const openFeedback = () => {
const phoneNumber = props.orderData.complaintHotline;
uni.makePhoneCall({ phoneNumber });
};
</script>
<style scoped lang="scss">
@use "./styles/index.scss";
</style>

View File

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

View File

@@ -0,0 +1,226 @@
@use "sass:color";
// SASS变量定义提高可维护性和编译性能
// 颜色系统
$order-bg-color: #fff;
$text-color-primary: #333;
$text-color-secondary: #666;
$text-color-accent: #ff5722;
$button-color: #00a6ff;
$button-hover-color: color.scale($button-color, $lightness: -16%);
$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;
// 动画关键帧
@keyframes loading-spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.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: 50px;
height: $button-height;
font-size: $font-size-medium;
font-weight: $font-weight-medium;
margin-top: $spacing-large;
position: relative;
overflow: hidden;
transition: all $transition-normal;
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 {
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;
}
// 加载动画
&::after {
content: "";
position: absolute;
left: 50%;
top: 50%;
width: 16px;
height: 16px;
margin: -8px 0 0 -8px;
border: 2px solid transparent;
border-top: 2px solid #fff;
border-radius: 50%;
animation: loading-spin 1s linear infinite;
}
}
}
.feedback {
text-align: center;
font-size: $font-size-medium;
color: $text-color-primary;
font-weight: $font-weight-normal;
margin-top: $spacing-medium;
}
}