Compare commits

10 Commits

Author SHA1 Message Date
086d61a587 feat: yarn i 2025-10-09 17:50:46 +08:00
duanshuwen
0bffc08a93 fix: 退款异常问题修复 2025-10-07 17:59:25 +08:00
duanshuwen
f095e12b46 fix: 还原退款 2025-10-07 17:24:07 +08:00
duanshuwen
f95a51cad8 fix: 退款问题修复 2025-10-07 17:19:45 +08:00
duanshuwen
500c44ebea fix: 待支付|再次预定交互逻辑调整 2025-10-07 16:31:35 +08:00
duanshuwen
3646870695 feat: 修复商品下单节流 2025-10-07 14:26:17 +08:00
duanshuwen
56f7f9d426 feat: 字体大小16px替换全局变量 2025-10-06 17:35:29 +08:00
duanshuwen
637c5f674b feat: 圆角50px替换全局变量 2025-10-06 17:30:17 +08:00
duanshuwen
dad5c4cc5e feat: 圆角50%替换全局变量|颜色#999替换全局变量 2025-10-06 17:25:28 +08:00
duanshuwen
6f477f3513 feat: 订单卡片图片图标替换成字体图标 2025-10-06 13:25:45 +08:00
39 changed files with 12941 additions and 774 deletions

4
.npmrc Normal file
View File

@@ -0,0 +1,4 @@
registry=https://registry.npmmirror.com
sass_binary_site=https://cdn.npmmirror.com/binaries/node-sass
shamefully-hoist=true

12097
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -80,7 +80,7 @@ $font-size-label: 10px;
justify-content: center;
width: 32px;
height: 32px;
border-radius: 50%;
border-radius: $uni-border-radius-circle;
transition: background-color 0.2s;
&:active {

View File

@@ -28,7 +28,7 @@
width: 24px;
height: 24px;
margin-right: 8px;
border-radius: 50%;
border-radius: $uni-border-radius-circle;
background-color: #ffa500;
display: flex;
align-items: center;
@@ -54,7 +54,7 @@
top: -8px;
width: 16px;
height: 16px;
border-radius: 50px;
border-radius: $uni-border-radius-50px;
background-color: #eff6fa;
}

View File

@@ -48,7 +48,7 @@ $form-transition: all 0.2s ease;
.form-title {
margin-left: 8px;
font-size: 16px;
font-size: $uni-font-size-lg;
font-weight: 500;
color: $form-primary-color;
flex: 1;

View File

@@ -19,7 +19,7 @@
right: 8px;
z-index: 10;
background: rgba(0, 0, 0, 0.5);
border-radius: 50px;
border-radius: $uni-border-radius-50px;
padding: 3px 8px;
font-size: 8px;
color: #fff;

View File

@@ -15,7 +15,7 @@
.order-icon {
width: 20px;
height: 20px;
border-radius: 50%;
border-radius: $uni-border-radius-circle;
background-color: #ffa500;
display: flex;
align-items: center;
@@ -24,7 +24,7 @@
}
.order-title {
font-size: 16px;
font-size: $uni-font-size-lg;
color: $uni-text-color;
}
@@ -35,7 +35,7 @@
}
.status-canceled {
color: #999;
color: $uni-text-color-grey;
border: 1px solid #999;
}

View File

@@ -43,7 +43,7 @@
.reject,
.agree {
border-radius: 50px;
border-radius: $uni-border-radius-50px;
width: 45%;
border: none;
font-size: 18px;
@@ -57,7 +57,7 @@
.reject {
color: #000;
background-color: #f5f5f5;
border-radius: 50px;
border-radius: $uni-border-radius-50px;
}
.agree {

View File

@@ -49,5 +49,5 @@
font-size: $uni-font-size-sm;
font-weight: 500;
color: #00a6ff;
border-radius: 50px;
border-radius: $uni-border-radius-50px;
}

View File

@@ -109,7 +109,7 @@ defineExpose({
align-items: center;
background-color: #00a6ff;
height: 44px;
border-radius: 50px;
border-radius: $uni-border-radius-50px;
}
.audio-visualizer {

View File

@@ -5,7 +5,7 @@
.stepper-text {
width: 40px;
font-size: 16px;
font-size: $uni-font-size-lg;
color: $uni-text-color;
text-align: center;
}

View File

@@ -24,7 +24,7 @@
.sum-value {
font-size: $uni-font-size-base;
color: #999;
color: $uni-text-color-grey;
}
.sum-discount {

View File

@@ -7,7 +7,7 @@
.notice-title {
display: flex;
align-items: center;
font-size: 16px;
font-size: $uni-font-size-lg;
font-weight: 500;
color: $uni-text-color;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 549 B

View File

@@ -7,11 +7,14 @@
<view class="order-title">
{{ orderData.workOrderTypeName || orderData.commodityName }}
</view>
<image
v-if="props.orderData.orderType !== undefined"
<uni-icons
class="arrow-icon"
src="./images/arrow.png"
></image>
v-if="props.orderData.orderType !== undefined"
type="right"
color="#999"
size="16"
/>
</view>
<view
v-if="orderData.status !== 'pending'"
@@ -33,7 +36,7 @@
</template>
<script setup>
import { defineProps, defineExpose } from "vue";
import { defineProps } from "vue";
import Divider from "@/components/Divider/index.vue";
import OrderCardContent from "./OrderCardContent.vue";
import serviceIcon from "./images/service.png";

View File

@@ -27,7 +27,7 @@
v-if="shouldShowButton"
:class="['reserve-button', { loading: isLoading }]"
:disabled="isLoading"
@click="handleButtonClick"
@click="handleButtonClick(orderData)"
>
{{ isLoading ? "处理中..." : buttonText }}
</button>
@@ -52,7 +52,7 @@ const PAY_WAY_MAP = {
const isLoading = ref(false);
// 定义事件发射器
const emit = defineEmits(["show-refund-popup"]);
const emit = defineEmits(["show-refund-popup", "pay-success"]);
const props = defineProps({
orderData: {
@@ -102,51 +102,95 @@ const shouldShowButton = computed(() => {
});
// 处理按钮点击事件
const handleButtonClick = async () => {
const handleButtonClick = async (orderData) => {
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);
const status = orderData.orderStatus;
// 仅作为示例,非真实参数信息。
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));
},
});
if (status === "2") {
// 情况2待使用状态显示退款弹窗
emit("show-refund-popup");
return; // 直接返回,不执行后续代码
}
// 再次预定跳转商品详情
if (["3", "5", "6"].includes(status)) {
uni.navigateTo({
url: `/pages/goods/index?commodityId=${orderData.commodityId}`,
});
}
// 待支付状态,调用支付接口
if (status === "0") {
const orderId = orderData.orderId;
const payWay = orderData.payWay;
const paySource = orderData.paySource;
const res = await orderPayNow({ orderId, payWay, paySource });
console.log("确认订单---2:", res);
// 检查接口返回数据
if (!res || !res.data) {
uni.showToast({
title: "订单创建失败,请重试",
icon: "none",
duration: 2000,
});
return;
}
const { data } = res;
const { nonceStr, packageVal, paySign, signType, timeStamp } = data;
// 验证支付参数是否完整
if (!nonceStr || !packageVal || !paySign || !signType || !timeStamp) {
console.error("支付参数不完整:", {
nonceStr: !!nonceStr,
packageVal: !!packageVal,
paySign: !!paySign,
signType: !!signType,
timeStamp: !!timeStamp,
});
uni.showToast({
title: "支付参数错误,请重试",
icon: "none",
duration: 2000,
});
return;
}
// 调用微信支付
uni.requestPayment({
provider: "wxpay",
timeStamp: String(timeStamp), // 确保为字符串类型
nonceStr: String(nonceStr),
package: String(packageVal), // 确保为字符串类型
signType: String(signType),
paySign: String(paySign),
success: () => {
uni.showToast({
title: "支付成功",
icon: "success",
duration: 2000,
success: () => {
emit("pay-success");
},
});
},
fail: (err) => {
uni.showToast({
title: "支付失败,请重试",
icon: "none",
duration: 2000,
});
},
});
}
} catch (error) {
console.error("操作失败:", error);
uni.showToast({
title: error.message || "操作失败,请重试",
icon: "none",
});
} finally {
isLoading.value = false;
}

View File

@@ -28,16 +28,6 @@ $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;
@@ -122,7 +112,7 @@ $transition-normal: 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50px;
border-radius: $uni-border-radius-50px;
height: $button-height;
font-size: $font-size-medium;
font-weight: $font-weight-medium;
@@ -153,21 +143,6 @@ $transition-normal: 0.3s ease;
&::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;
}
}
}

View File

@@ -98,7 +98,7 @@ const refundAmount = computed(() => {
});
// 是否可退款
const isRefundable = computed(() => !props.orderData.refundable);
const isRefundable = computed(() => props.orderData.refundable);
// 按钮文件
const btnText = computed(() => (isRefundable.value ? "点击退款" : "我知道了"));

View File

@@ -25,7 +25,7 @@
}
&__title {
font-size: 16px;
font-size: $uni-font-size-lg;
font-weight: 500;
color: $uni-text-color;
line-height: 22px;
@@ -94,7 +94,7 @@
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
font-size: $uni-font-size-lg;
transition: all 0.3s ease;
outline: none;

View File

@@ -30,7 +30,7 @@
.tab-text-active {
color: $uni-text-color;
font-size: 16px;
font-size: $uni-font-size-lg;
font-weight: 600;
}

View File

@@ -5,7 +5,7 @@
}
.user-info-title {
font-size: 16px;
font-size: $uni-font-size-lg;
font-weight: 600;
margin-bottom: 14px;
}

View File

@@ -23,7 +23,11 @@
<GoodsInfo :orderData="orderData" />
<UserInfo :orderData="orderData" />
<NoticeInfo :orderData="orderData" />
<OrderInfo :orderData="orderData" @show-refund-popup="showRefundPopup" />
<OrderInfo
:orderData="orderData"
@show-refund-popup="showRefundPopup"
@pay-success="handlePaySuccess"
/>
<!-- 退款状态显示 -->
<RefundPopup
@@ -51,12 +55,14 @@ import RefundPopup from "./components/RefundPopup/index.vue";
const refundVisible = ref(false);
const orderData = ref({});
onLoad(async ({ orderId }) => {
const res = await userOrderDetail({ orderId });
onLoad(({ orderId }) => getOrderDetail(orderId));
// 获取订单详情
const getOrderDetail = async (orderId) => {
const res = await userOrderDetail({ orderId });
orderData.value = res.data;
console.log(res);
});
};
// 监听页面滚动事件
const backgroundColor = ref("transparent");
@@ -105,6 +111,11 @@ const handleRefundConfirm = async ({ orderId }) => {
});
}
};
// 再次预定
const handlePaySuccess = ({ orderId }) => {
getOrderDetail(orderId);
};
</script>
<style lang="scss" scoped>

View File

@@ -16,7 +16,7 @@
top: -12rpx;
left: 24rpx;
font-size: 20rpx;
color: #999999;
color: $uni-text-color-grey;
background-color: $uni-bg-color;
padding: 0 8rpx;
z-index: 1;

View File

@@ -62,7 +62,7 @@
justify-content: space-between;
.goods-title {
font-size: 16px;
font-size: $uni-font-size-lg;
font-weight: 500;
color: $uni-text-color;
line-height: 22px;
@@ -93,7 +93,7 @@
.price-desc {
font-size: $uni-font-size-base;
color: #999;
color: $uni-text-color-grey;
font-weight: 400;
margin-left: 12px;
}
@@ -129,7 +129,7 @@
}
.service-value {
color: #999;
color: $uni-text-color-grey;
}
}
}
@@ -189,7 +189,7 @@
color: #fff;
border: none;
border-radius: 24px;
font-size: 16px;
font-size: $uni-font-size-lg;
font-weight: 600;
display: flex;
align-items: center;

View File

@@ -8,7 +8,7 @@
margin-bottom: 12px;
.title {
font-size: 16px;
font-size: $uni-font-size-lg;
color: $uni-text-color;
font-weight: 600;
line-height: 1.4;

View File

@@ -70,6 +70,7 @@ import {
commodityDailyPriceList,
orderPay,
} from "@/request/api/GoodsApi";
import { ThrottleUtils } from "@/utils";
import TopNavBar from "@/components/TopNavBar/index.vue";
import ImageSwiper from "@/components/ImageSwiper/index.vue";
import GoodInfo from "./components/GoodInfo/index.vue";
@@ -122,6 +123,19 @@ const goodsInfo = async (params) => {
commodityId: goodsData.value.commodityId,
});
}
if (goodsData.value.commodityStatus !== "1") {
uni.showModal({
title: "温馨提示",
content: "商品已下架,是否返回上一页?",
success: (res) => {
if (res.confirm) {
uni.navigateBack({ delta: 1 });
}
},
});
return;
}
};
const configGoodsData = () => {
@@ -164,7 +178,7 @@ const showConfirmPopup = () => {
};
// 处理确认订单
const handleConfirmOrder = async (orderData) => {
const handleConfirmOrder = ThrottleUtils.createThrottle(async (orderData) => {
console.log("确认订单---1:", orderData);
const { goodsData } = orderData;
// 购买的商品id
@@ -260,7 +274,7 @@ const handleConfirmOrder = async (orderData) => {
});
},
});
};
}, 1000);
// 处理关闭弹窗
const handleCloseConfirm = () => {

View File

@@ -116,7 +116,7 @@ $button-color: #00a6ff;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50px;
border-radius: $uni-border-radius-50px;
height: 42px;
font-size: $uni-font-size-base;
font-weight: 500;

View File

@@ -30,7 +30,7 @@
width: 100%;
height: 44px;
color: $uni-text-color;
font-size: 16px;
font-size: $uni-font-size-lg;
display: flex;
justify-content: center;
align-items: center;
@@ -68,7 +68,7 @@
width: 100%;
max-height: 92px;
min-height: 22px;
font-size: 16px;
font-size: $uni-font-size-lg;
line-height: 22px;
margin: 6px 0;

View File

@@ -27,7 +27,7 @@
.avatar-row .avatar {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
border-radius: $uni-border-radius-circle;
}
.label {

View File

@@ -18,7 +18,7 @@
display: inline-block;
width: 3px;
height: 3px;
border-radius: 50%;
border-radius: $uni-border-radius-circle;
margin-right: 3px;
background: #333333;
animation: wave 1.3s linear infinite;

View File

@@ -60,7 +60,7 @@
}
.card-title {
font-size: 16px;
font-size: $uni-font-size-lg;
font-weight: bold;
color: #222;
width: 100%;
@@ -113,7 +113,7 @@
.card-price {
color: #ff6600;
font-size: 16px;
font-size: $uni-font-size-lg;
font-weight: bold;
}
.card-unit {

View File

@@ -24,7 +24,7 @@
.label {
font-size: 24rpx;
color: #999;
color: $uni-text-color-grey;
}
.date {
font-size: 28rpx;
@@ -54,4 +54,4 @@
font-size: 22rpx;
color: #666;
margin-top: 4rpx;
}
}

View File

@@ -59,7 +59,7 @@
}
.card-title {
font-size: 16px;
font-size: $uni-font-size-lg;
font-weight: bold;
color: #222;
width: 100%;
@@ -112,7 +112,7 @@
.card-price {
color: #ff6600;
font-size: 16px;
font-size: $uni-font-size-lg;
font-weight: bold;
}
.card-unit {

View File

@@ -32,7 +32,7 @@
&:hover {
background: #f5f5f5;
border-radius: 50%;
border-radius: $uni-border-radius-circle;
}
}
}
@@ -65,8 +65,8 @@
align-items: center;
justify-content: center;
color: #ffffff;
border-radius: 50px;
font-size: 16px;
border-radius: $uni-border-radius-50px;
font-size: $uni-font-size-lg;
font-weight: 500;
transition: all 0.3s ease;

View File

@@ -51,7 +51,7 @@
.login-btn {
background: linear-gradient(246deg, #22a7ff 0%, #2567ff 100%);
width: 100%;
border-radius: 50px;
border-radius: $uni-border-radius-50px;
}
}

View File

@@ -9,15 +9,15 @@ const userWorkOrderList = (args) => {
return request.post("/hotelBiz/workOrder/userWorkOrderList", args);
};
/// 获取工单类型
// 获取工单类型
const workOrderTypeListForBiz = () => {
return request.get('/hotelBiz/workOrder/workOrderTypeListForBiz', {});
}
return request.get("/hotelBiz/workOrder/workOrderTypeListForBiz", {});
};
/// 创建工单
// 创建工单
const createWorkOrder = (args) => {
return request.post('/hotelBiz/workOrder/createWorkOrder', args);
}
return request.post("/hotelBiz/workOrder/createWorkOrder", args);
};
// 获取订单详情
const userOrderDetail = (args) => {

View File

@@ -21,37 +21,38 @@ $uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* 文字基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
$uni-text-color: #333; //基本色
$uni-text-color-inverse: #fff; //反色
$uni-text-color-grey: #999; //辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
$uni-text-color-disable: #c0c0c0;
/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
$uni-bg-color: #ffffff;
$uni-bg-color-grey: #f8f8f8;
$uni-bg-color-hover: #f1f1f1; //点击状态颜色
$uni-bg-color-mask: rgba(0, 0, 0, 0.4); //遮罩颜色
/* 边框颜色 */
$uni-border-color:#c8c7cc;
$uni-border-color: #c8c7cc;
/* 尺寸变量 */
/* 文字尺寸 */
$uni-font-size-sm:12px;
$uni-font-size-base:14px;
$uni-font-size-lg:16px;
$uni-font-size-sm: 12px;
$uni-font-size-base: 14px;
$uni-font-size-lg: 16px;
/* 图片尺寸 */
$uni-img-size-sm:20px;
$uni-img-size-base:26px;
$uni-img-size-lg:40px;
$uni-img-size-sm: 20px;
$uni-img-size-base: 26px;
$uni-img-size-lg: 40px;
/* Border Radius */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-50px: 50px;
$uni-border-radius-circle: 50%;
/* 水平间距 */
@@ -68,9 +69,9 @@ $uni-spacing-col-lg: 12px;
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
/* 文章场景相关 */
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:20px;
$uni-color-title: #2c405a; // 文章标题颜色
$uni-font-size-title: 20px;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:26px;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:15px;
$uni-font-size-subtitle: 26px;
$uni-color-paragraph: #3f536e; // 文章段落颜色
$uni-font-size-paragraph: 15px;

View File

@@ -18,7 +18,7 @@ export class IdUtils {
const randomStr = Array.from({ length: 4 }, () =>
chars.charAt(Math.floor(Math.random() * chars.length))
).join("");
return "mid"+ randomStr + timestamp;
return "mid" + randomStr + timestamp;
}
}
@@ -250,10 +250,61 @@ export class TimerUtils {
}
}
/**
* 防抖工具类
* 提供防抖功能,防止函数在短时间内被重复调用
*/
export class DebounceUtils {
/**
* 创建防抖函数
* @param {Function} func - 要防抖的函数
* @param {number} delay - 防抖延迟时间
* @returns {Function} 防抖后的函数
*/
static createDebounce(func, delay) {
let timerId = null;
return function (...args) {
if (timerId) {
clearTimeout(timerId);
}
timerId = setTimeout(() => func.apply(this, args), delay);
};
}
}
/**
* 节流工具类
* 提供节流功能,防止函数在短时间内被重复调用
*/
export class ThrottleUtils {
/**
* 创建节流函数
* @param {Function} func - 要节流的函数
* @param {number} delay - 节流延迟时间
* @returns {Function} 节流后的函数
*/
static createThrottle(func, delay) {
let prev = Date.now();
return function (...args) {
let now = Date.now();
if (now - prev >= delay) {
func.apply(this, args);
prev = now;
}
};
}
}
// 默认导出所有工具类
export default {
IdUtils,
CallbackUtils,
MessageUtils,
TimerUtils,
DebounceUtils,
ThrottleUtils,
};

1227
yarn.lock

File diff suppressed because it is too large Load Diff