You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

504 lines
10 KiB

<template>
<view class="write-off-container">
<scroll-view class="content-scroll" scroll-y>
<!-- 核销码展示区域 -->
<view class="code-section">
<view class="section-title">
<text>核销码</text>
</view>
<view class="code-card">
<!-- 二维码 -->
<view class="qr-code-container">
<img :src="goodsInfo.orderVerification.qrCodeUrl" class="qr-code" />
<!-- <canvas canvas-id="qrcode" class="qr-code"></canvas> -->
</view>
<!-- 兑换码 -->
<view class="exchange-code">
<text class="code-label">兑换码</text>
<text class="code-value">{{
(goodsInfo.orderVerification &&
goodsInfo.orderVerification.verifyCode) ||
""
}}</text>
<view class="copy-btn" @click="copyCode">
<uni-icons type="copy" size="16" color="#667eea" />
<text>复制</text>
</view>
</view>
</view>
</view>
<!-- 预约信息 -->
<view class="reservation-section" v-if="goodsInfo.reservationTime">
<view class="section-title">
<text>预约信息</text>
</view>
<view class="reservation-card">
<view class="reservation-item">
<text class="reservation-label">预约核销日期</text>
<text class="reservation-value">{{
goodsInfo.reservationTime
}}</text>
</view>
</view>
</view>
<!-- 商品信息 -->
<view class="goods-section">
<view class="section-title">
<text>商品信息</text>
</view>
<view class="goods-card">
<image
class="goods-image"
:src="goodsInfo.goodsImage.split(',')[0]"
mode="aspectFill"
/>
<view class="goods-info">
<text class="goods-name">{{ goodsInfo.goodsName || "--" }}</text>
<view class="specs-info">
<view
class="spec-item"
v-for="(spec, index) in goodsInfo.orderReservationDetails"
:key="index"
>
<text class="spec-label">第{{ index + 1 }}份规格:</text>
<text class="spec-value"
>{{ spec.specValueOne }}/{{ spec.specValueTwo }}</text
>
</view>
</view>
</view>
</view>
</view>
<!-- 使用说明 -->
<view class="instruction-section">
<view class="section-title">
<text>使用说明</text>
</view>
<view class="instruction-card">
<view class="instruction-item">
<text class="instruction-text"
>1.
<text class="expiry-highlight"
>有效期至{{
goodsInfo.expireTime || ""
}},到期后将自动退款至原支付账户</text
></text
>
</view>
<view class="instruction-item">
<text class="instruction-text">2. 请在预约时间内到店核销</text>
</view>
<view class="instruction-item">
<text class="instruction-text"
>3. 出示此页面或提供兑换码给工作人员</text
>
</view>
<view class="instruction-item">
<text class="instruction-text">4. 核销后商品不可退换</text>
</view>
</view>
</view>
<view class="bottom-space"></view>
</scroll-view>
<!-- 底部操作区域 -->
<view class="bottom-actions">
<button class="cancel-btn" @click="cancelReservation">取消预约</button>
</view>
</view>
</template>
<script>
import QRCode from "@/static/js/weapp-qrcode.js";
export default {
data() {
return {
orderId: "",
goodsInfo: {},
};
},
onLoad(options) {
// 接收页面参数
if (options.orderChildId) {
this.orderChildId = options.orderChildId;
}
},
onShow() {
this.generateExchangeCode();
},
onReady() {
// 生成二维码
this.generateQRCode();
},
methods: {
generateExchangeCode() {
this.Post(
{
orderChildId: this.orderChildId,
},
"/framework/orderReservation/getCanByOrderChildId",
"DES"
).then((res) => {
if (res.code == 200) {
this.goodsInfo = res.data;
}
});
},
// 生成二维码
generateQRCode() {
const qrData = JSON.stringify({
orderId: this.orderId,
exchangeCode: this.goodsInfo.exchangeCode,
type: "writeOff",
});
// 使用weapp-qrcode生成二维码
QRCode({
canvasId: "qrcode",
text: qrData,
width: 200,
height: 200,
colorDark: "#000000",
colorLight: "#ffffff",
correctLevel: QRCode.CorrectLevel.M,
component: this,
});
},
// 复制兑换码
copyCode() {
uni.setClipboardData({
data: this.goodsInfo.orderVerification.verifyCode,
success: () => {
uni.showToast({
title: "兑换码已复制",
icon: "success",
});
},
});
},
// 取消预约
cancelReservation() {
uni.showModal({
title: "确认取消",
content: "确定要取消此次预约吗?取消后将无法恢复。",
success: (res) => {
if (res.confirm) {
this.performCancelReservation();
}
},
});
},
// 执行取消预约
performCancelReservation() {
uni.showLoading({
title: "取消中...",
});
this.Post(
{
orderChildId: this.orderChildId,
},
"/framework/orderReservation/cancel",
"DES"
)
.then((res) => {
uni.hideLoading();
if (res.code == 200) {
uni.showToast({
title: "取消成功",
icon: "success",
});
setTimeout(() => {
uni.navigateBack();
}, 800);
} else {
uni.showToast({
title: res.msg || "取消失败",
icon: "none",
});
}
})
.catch(() => {
uni.hideLoading();
uni.showToast({
title: "网络错误",
icon: "none",
});
});
},
},
};
</script>
<style lang="scss" scoped>
// 主题色彩变量
$primary-color: #667eea;
$secondary-color: #f8f9fa;
$text-primary: #2d3748;
$text-secondary: #718096;
$text-muted: #a0aec0;
$border-color: #e2e8f0;
$success-color: #48bb78;
$warning-color: #ed8936;
$danger-color: #f56565;
$bg-light: #f7fafc;
.write-off-container {
height: 100vh;
background-color: $bg-light;
display: flex;
flex-direction: column;
}
.content-scroll {
flex: 1;
padding: 20rpx;
width: 710rpx;
}
.section-title {
font-size: 28rpx;
color: $text-primary;
font-weight: 600;
margin-bottom: 16rpx;
}
// 核销码区域
.code-section {
margin-bottom: 24rpx;
}
.code-card {
background-color: #ffffff;
border-radius: 16rpx;
padding: 40rpx;
display: flex;
flex-direction: column;
align-items: center;
gap: 30rpx;
}
.qr-code-container {
display: flex;
justify-content: center;
align-items: center;
}
.qr-code {
width: 250rpx;
height: 250rpx;
border: 2rpx solid $border-color;
border-radius: 8rpx;
}
.exchange-code {
display: flex;
flex-direction: column;
align-items: center;
gap: 12rpx;
width: 100%;
}
.code-label {
font-size: 24rpx;
color: $text-secondary;
}
.code-value {
font-size: 36rpx;
color: $text-primary;
font-weight: 600;
font-family: "SF Mono", "Monaco", "Cascadia Code", monospace;
letter-spacing: 4rpx;
}
.copy-btn {
display: flex;
align-items: center;
gap: 8rpx;
padding: 12rpx 24rpx;
background-color: rgba(102, 126, 234, 0.1);
border-radius: 20rpx;
transition: all 0.3s ease;
&:active {
background-color: rgba(102, 126, 234, 0.2);
transform: scale(0.95);
}
text {
font-size: 24rpx;
color: $primary-color;
font-weight: 500;
}
}
// 商品信息
.goods-section {
margin-bottom: 24rpx;
}
.goods-card {
display: flex;
background-color: #ffffff;
border-radius: 16rpx;
padding: 24rpx;
gap: 20rpx;
}
.goods-image {
width: 120rpx;
height: 120rpx;
border-radius: 12rpx;
flex-shrink: 0;
}
.goods-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 12rpx;
}
.goods-name {
font-size: 26rpx;
color: $text-primary;
font-weight: 600;
line-height: 1.4;
}
.specs-info {
display: flex;
flex-direction: column;
gap: 8rpx;
}
.spec-item {
display: flex;
align-items: center;
gap: 8rpx;
}
.spec-label {
font-size: 24rpx;
color: $text-secondary;
}
.spec-value {
font-size: 24rpx;
color: $text-primary;
font-weight: 500;
}
// 预约信息
.reservation-section {
margin-bottom: 24rpx;
}
.reservation-card {
background-color: #ffffff;
border-radius: 16rpx;
padding: 24rpx;
}
.reservation-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8rpx 0;
&:not(:last-child) {
border-bottom: 1rpx solid $border-color;
}
}
.reservation-label {
font-size: 26rpx;
color: $text-secondary;
}
.reservation-value {
font-size: 26rpx;
color: $text-primary;
font-weight: 500;
}
// 使用说明
.instruction-section {
margin-bottom: 24rpx;
}
.instruction-card {
background-color: #ffffff;
border-radius: 16rpx;
padding: 24rpx;
}
.instruction-item {
padding: 12rpx 0;
border-bottom: 1rpx solid $border-color;
&:last-child {
border-bottom: none;
}
}
.instruction-text {
font-size: 24rpx;
color: $text-secondary;
line-height: 1.5;
}
.expiry-highlight {
color: #ff6b35;
font-weight: 500;
}
.bottom-space {
height: 120rpx;
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
box-sizing: content-box;
}
// 底部操作区域
.bottom-actions {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 24rpx;
background-color: #ffffff;
border-top: 1rpx solid $border-color;
box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.04);
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
z-index: 100;
.cancel-btn {
width: 100%;
background-color: $danger-color;
color: #ffffff;
border: none;
border-radius: 24rpx;
padding: 16rpx;
font-size: 28rpx;
font-weight: 600;
transition: all 0.3s ease;
&:active {
transform: scale(0.95);
background-color: rgba(245, 101, 101, 0.8);
}
}
}
</style>