979 lines
23 KiB
Vue
979 lines
23 KiB
Vue
<template>
|
|
<page-meta :page-style="`overflow:${show9 ? 'hidden' : 'visible'};`"></page-meta>
|
|
<view class="verification-page">
|
|
<!-- 自定义导航栏 -->
|
|
<wd-navbar :bordered="false"
|
|
custom-style="background: transparent !important; backdrop-filter: blur(10px) !important; -webkit-backdrop-filter: blur(10px) !important;"
|
|
safeAreaInsetTop fixed placeholder>
|
|
<template #left>
|
|
<view class="li-ml-15 li-mt-10 li-flex li-items-center">
|
|
<text v-if="hasMultiplePages" class="ri-arrow-left-s-line li-text-70 "
|
|
@click="toPages({type:'nav'})"></text>
|
|
<text v-if="!hasMultiplePages" class="ri-home-5-line li-text-55 li-mb-8 li-mr-10 "
|
|
@click="toPages({type:'home'})"></text>
|
|
<text class="li-text-42 ">商品核销</text>
|
|
</view>
|
|
</template>
|
|
<!-- #ifdef MP-WEIXIN -->
|
|
<template #right>
|
|
<view class="li-flex-center li-mr-200" @click="toVerificationHistory">
|
|
<text class="ri-history-line li-text-48"></text>
|
|
</view>
|
|
</template>
|
|
|
|
<!-- #endif -->
|
|
<!-- #ifndef MP-WEIXIN -->
|
|
<template #right>
|
|
<view class="li-flex-center li-mr-25" @click="toVerificationHistory">
|
|
<text class="ri-history-line li-text-48"></text>
|
|
</view>
|
|
</template>
|
|
<!-- #endif -->
|
|
</wd-navbar>
|
|
|
|
<!-- 功能模式切换卡片 -->
|
|
<view class="mode-switch-card">
|
|
<view class="mode-tabs">
|
|
<view class="mode-tab" :class="{'active': activeMode === 0}" @click="activeMode = 0">
|
|
<text class="ri-qr-scan-line tab-icon"></text>
|
|
<text class="tab-text">扫码核销</text>
|
|
</view>
|
|
<view class="mode-tab" :class="{'active': activeMode === 1}" @click="activeMode = 1">
|
|
<text class="ri-keyboard-line tab-icon"></text>
|
|
<text class="tab-text">手动输入</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view v-if="activeMode === 0" class="continuous-switch">
|
|
<wd-tooltip placement="bottom-start" content="开启后可以连续核销多个订单">
|
|
<view class="li-flex li-items-center li-mr-10">
|
|
<view class="li-mr-4 li-text-28 li-text-#666">连续核销</view>
|
|
<text class="ri-question-fill li-text-36 li-text-#666"></text>
|
|
</view>
|
|
</wd-tooltip>
|
|
<wd-switch v-model="continuousMode" active-color="#42D3AA" size="24" />
|
|
</view>
|
|
|
|
<!-- 功能区域 - 根据当前模式显示不同内容 -->
|
|
<!-- 扫码模式 -->
|
|
<view v-if="activeMode === 0" class="scan-mode-container">
|
|
<view class="scan-hexagon" @click="scanCode">
|
|
<view class="scan-inner" :class="{'scanning': isScanning}">
|
|
<text class="ri-qr-scan-2-line scan-icon"></text>
|
|
<view class="scan-lines">
|
|
<view class="scan-line"></view>
|
|
<view class="scan-line"></view>
|
|
<view class="scan-line"></view>
|
|
</view>
|
|
</view>
|
|
<view class="hexagon-overlay"></view>
|
|
</view>
|
|
<view class="scan-prompt">
|
|
<text class="prompt-text">点击扫描二维码核销</text>
|
|
<text v-if="continuousMode" class="sub-prompt">连续核销模式已开启</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 手动输入模式 -->
|
|
<view v-else class="input-mode-container">
|
|
<view class="input-card">
|
|
<view class="input-title">请输入订单号</view>
|
|
<wd-input v-model="orderNumber" placeholder="请输入需要核销的订单号" clearable custom-class="custom-input" />
|
|
<view class="verify-button-view">
|
|
<wd-button type="primary" @click="submitOrderNumber" custom-class="verify-button">立即核销</wd-button>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 连续核销模式下的结果展示区域 -->
|
|
<view v-if="verificationRecords.length > 0" class="records-section">
|
|
<view class="section-title">
|
|
<text class="title-icon ri-file-list-3-line"></text>
|
|
<text class="title-text">最近核销记录</text>
|
|
</view>
|
|
|
|
<view class="records-list">
|
|
<view v-for="(record, index) in verificationRecords" :key="index" @click="recordetail(record)"
|
|
class="record-card">
|
|
<view class="record-header">
|
|
<text class="order-number">{{record.order_no}}</text>
|
|
<view class="status-badge">核销成功</view>
|
|
</view>
|
|
<view class="record-time">
|
|
<text class="ri-time-line time-icon"></text>
|
|
<text class="time-text">{{record.create_time}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 空状态提示 -->
|
|
<view v-if="verificationRecords.length==0" class="empty-state">
|
|
<wd-status-tip :image="uni.$globalData?.RESOURCE_URL+'tip/search.png'" image="search" tip="暂无核销记录" />
|
|
</view>
|
|
|
|
<!-- 顶部提示条(成功/失败消息提示) -->
|
|
<wd-toast />
|
|
|
|
<!-- 商品确认弹出框 -->
|
|
<wd-popup v-model="show9" position="bottom" closable :safe-area-inset-bottom="true"
|
|
custom-style="height: auto; max-height: 80vh;">
|
|
<view class="confirm-popup">
|
|
<view class="popup-header">
|
|
<text class="ri-checkbox-circle-line check-icon"></text>
|
|
<text class="header-title">商品确认 ({{orderInfo?.product?.length}}件)</text>
|
|
</view>
|
|
<scroll-view scroll-y class="popup-scroll">
|
|
<view class="popup-content">
|
|
<view v-for="(item, index) in orderInfo.product" :key="index" class="product-card">
|
|
<view class="product-main">
|
|
<view class="product-image-container" @click="previewImage(item.picture)">
|
|
<image :src="item.picture" mode="aspectFill" class="product-img"></image>
|
|
<view class="zoom-overlay">
|
|
<text class="ri-zoom-in-line zoom-icon"></text>
|
|
</view>
|
|
</view>
|
|
<view class="product-details">
|
|
<text class="product-name">{{item.product_name}}</text>
|
|
<text class="product-spec">规格: {{item.spec_name}}</text>
|
|
<view class="product-quantity">
|
|
<text class="quantity-label">数量:</text>
|
|
<text class="quantity-value">{{item.num}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view v-if="index !== orderInfo?.product?.length - 1" class="product-divider"></view>
|
|
</view>
|
|
|
|
<view class="order-details">
|
|
<view class="details-title">订单信息</view>
|
|
<view class="details-grid">
|
|
<view class="detail-item">
|
|
<view class="detail-content">
|
|
<text class="detail-icon ri-barcode-line"></text>
|
|
<text class="detail-label">订单号</text>
|
|
</view>
|
|
<text class="detail-value">{{orderInfo.order_no}}</text>
|
|
</view>
|
|
<view class="detail-item">
|
|
<view class="detail-content">
|
|
<text class="detail-icon ri-calendar-line"></text>
|
|
<text class="detail-label">下单时间</text>
|
|
</view>
|
|
<text class="detail-value">{{orderInfo.create_time}}</text>
|
|
</view>
|
|
|
|
<view class="detail-item">
|
|
<view class="detail-content">
|
|
<text class="detail-icon ri-user-line"></text>
|
|
<text class="detail-label">操作人</text>
|
|
</view>
|
|
<text class="detail-value">{{userInfo.realname}}</text>
|
|
</view>
|
|
<view class="detail-item">
|
|
<view class="detail-content">
|
|
<text class="detail-icon ri-store-line"></text>
|
|
<text class="detail-label">负责仓库</text>
|
|
</view>
|
|
<text class="detail-value">{{orderInfo.distribute_name}}</text>
|
|
</view>
|
|
<view class="detail-item">
|
|
<view class="detail-content">
|
|
<text class="detail-icon ri-truck-line"></text>
|
|
<text class="detail-label">来源</text>
|
|
</view>
|
|
<text class="detail-value">{{orderInfo.supplier_name}}</text>
|
|
</view>
|
|
<view class="detail-item">
|
|
<view class="detail-content">
|
|
<text class="detail-icon ri-price-tag-3-line"></text>
|
|
<text class="detail-label">订单类型</text>
|
|
</view>
|
|
<text
|
|
class="detail-value">{{orderInfo.type==1?'普通订单':(orderInfo.type==2?'秒杀订单':'拼团订单')}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
<view class="popup-footer">
|
|
<wd-button type="primary" block :loading="isConfirming" custom-class="confirm-button"
|
|
@click="GetorderStorageVerify">
|
|
{{ isConfirming ? '处理中...' : '确认核销' }}
|
|
</wd-button>
|
|
<view class="cancel-text" @click="show9 = false">稍后处理</view>
|
|
</view>
|
|
</view>
|
|
</wd-popup>
|
|
<zero-loading type="wobble" v-if="loading"></zero-loading>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, reactive } from 'vue'
|
|
import { onLoad } from '@dcloudio/uni-app'
|
|
import { scanCodeGet, orderRecord, orderStorageVerify } from '@/api/ticket'
|
|
import { useNavigation } from '@/hooks/useNavigation'
|
|
import { useToast } from '@/uni_modules/wot-design-uni'
|
|
const Toast = useToast()
|
|
// 使用导航 composable
|
|
const {
|
|
hasMultiplePages, // 是否有多个页面在路由栈中
|
|
isTabBarPage, // 当前页面是否为 tabBar 页面
|
|
checkRouteStack // 检查当前路由栈状态的方法
|
|
} = useNavigation()
|
|
|
|
// 模式选择
|
|
const activeMode = ref(0) // 0: 扫码模式, 1: 手动输入模式
|
|
const continuousMode = ref(false) // 是否开启连续核销模式
|
|
const orderNumber = ref('') // 手动输入的订单号
|
|
const isScanning = ref(false) // 控制扫描动画
|
|
const isConfirming = ref(false) // 控制确认动画
|
|
const orderInfo = ref({}) //扫码订单详情
|
|
const userInfo = ref(uni.getStorageSync('userInfo'))
|
|
const loading = ref<boolean>(false)
|
|
|
|
// 核销记录
|
|
const verificationRecords = ref([
|
|
// 示例数据,实际应为空数组
|
|
{
|
|
orderNumber: 'JD202503050001',
|
|
time: '2025-03-05 21:58:34',
|
|
status: 'success' // success, fail, pending
|
|
}
|
|
])
|
|
|
|
const show9 = ref<boolean>(false)
|
|
|
|
// 扫码核销
|
|
const scanCode = async () => {
|
|
// 激活扫描动画
|
|
isScanning.value = true;
|
|
// 延迟显示弹窗并停止动画
|
|
setTimeout(() => {
|
|
isScanning.value = false;
|
|
// show9.value = true;
|
|
}, 800);
|
|
// handleVerification('20250326214053344401')
|
|
// return;
|
|
uni.scanCode({
|
|
success: (res) => {
|
|
handleVerification(res.result)
|
|
},
|
|
fail: (err) => {
|
|
Toast.error('扫码失败,请重试')
|
|
}
|
|
})
|
|
}
|
|
|
|
|
|
const GetorderStorageVerify = async () => {
|
|
// 添加动画效果和成功提示
|
|
isConfirming.value = true;
|
|
try {
|
|
const res = await orderStorageVerify({ order_id: orderInfo.value.order_id })
|
|
if (res.code == 200) {
|
|
Toast.success('商品核销成功');
|
|
show9.value = false;
|
|
orderNumber.value = '' // 清空输入
|
|
|
|
// 请求核销记录接口
|
|
getOrderRecord()
|
|
} else {
|
|
Toast.error(res.msg)
|
|
}
|
|
|
|
} catch (error) {
|
|
Toast.error('核销失败')
|
|
} finally {
|
|
isConfirming.value = false;
|
|
}
|
|
}
|
|
|
|
|
|
const contOrderStorageVerify = async () => {
|
|
try {
|
|
const res = await orderStorageVerify({ order_id: orderInfo.value.order_id })
|
|
console.log('contOrderStorageVerify', res);
|
|
if (res.code == 200) {
|
|
Toast.success('商品核销成功');
|
|
// 请求核销记录接口
|
|
getOrderRecord()
|
|
setTimeout(() => {
|
|
scanCode()
|
|
}, 1000)
|
|
} else {
|
|
Toast.error(res.msg)
|
|
}
|
|
|
|
} catch (error) {
|
|
Toast.error('核销失败')
|
|
} finally {
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 处理核销逻辑
|
|
const handleVerification = async (code) => {
|
|
const res = await scanCodeGet({ code: code })
|
|
if (res.code == 200) {
|
|
orderInfo.value = res.data
|
|
if (activeMode.value == 1) {
|
|
show9.value = true;
|
|
return
|
|
}
|
|
// 连续核销
|
|
if (continuousMode.value) {
|
|
contOrderStorageVerify()
|
|
} else {
|
|
// 非连续核销
|
|
show9.value = true;
|
|
}
|
|
} else {
|
|
Toast.error(res.msg)
|
|
}
|
|
|
|
}
|
|
|
|
// 提交订单号核销
|
|
const submitOrderNumber = () => {
|
|
if (!orderNumber.value) {
|
|
Toast.error('请输入订单号')
|
|
return
|
|
}
|
|
handleVerification(orderNumber.value)
|
|
}
|
|
|
|
const getOrderRecord = async () => {
|
|
try {
|
|
const res = await orderRecord({ page: 1, limit: 10, type: 2 })
|
|
verificationRecords.value = res.data
|
|
} catch (error) {
|
|
} finally {
|
|
}
|
|
}
|
|
|
|
// 格式化日期时间
|
|
const formatDateTime = (date : Date) : string => {
|
|
const year = date.getFullYear()
|
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
|
const day = String(date.getDate()).padStart(2, '0')
|
|
const hours = String(date.getHours()).padStart(2, '0')
|
|
const minutes = String(date.getMinutes()).padStart(2, '0')
|
|
const seconds = String(date.getSeconds()).padStart(2, '0')
|
|
|
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
|
}
|
|
|
|
// 跳转到核销历史记录页面
|
|
const toVerificationHistory = () => {
|
|
// 这里应该跳转到历史记录页面
|
|
// 目前示例仅显示提示
|
|
// Toast.info('查看历史记录')
|
|
uni.navigateTo({
|
|
url: '/pagesA/verification/history?type=2'
|
|
})
|
|
}
|
|
|
|
const recordetail = (item) => {
|
|
uni.navigateTo({
|
|
url: '/pagesA/verification/historyDetail?order_no=' + item.order_no + '&type=2'
|
|
})
|
|
}
|
|
|
|
// 页面跳转
|
|
const toPages = (item : any) => {
|
|
if (item.type === 'nav') {
|
|
uni.navigateBack()
|
|
} else if (item.type === 'home') {
|
|
// 这里是项目内部的跳转逻辑
|
|
uni.switchTab({
|
|
url: '/pages/index/index'
|
|
})
|
|
}
|
|
}
|
|
|
|
// 打开图片预览
|
|
const previewImage = (imageUrl) => {
|
|
uni.previewImage({
|
|
urls: [imageUrl],
|
|
current: 0,
|
|
indicator: 'number',
|
|
loop: true
|
|
})
|
|
}
|
|
|
|
onLoad(() => {
|
|
checkRouteStack()
|
|
// 请求核销记录接口
|
|
getOrderRecord()
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
page {
|
|
background-color: #f7f8fc;
|
|
}
|
|
|
|
.verification-page {
|
|
min-height: 100vh;
|
|
padding-bottom: 30rpx;
|
|
|
|
// 模式切换卡片
|
|
.mode-switch-card {
|
|
margin: 30rpx auto;
|
|
width: 90%;
|
|
background: linear-gradient(135deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.7));
|
|
backdrop-filter: blur(10px);
|
|
border-radius: 20rpx;
|
|
box-shadow: 0 10rpx 30rpx rgba(118, 98, 236, 0.08);
|
|
overflow: hidden;
|
|
|
|
.mode-tabs {
|
|
display: flex;
|
|
height: 100rpx;
|
|
|
|
.mode-tab {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
position: relative;
|
|
transition: all 0.3s;
|
|
|
|
&.active {
|
|
color: #42D3AA;
|
|
background: rgba(118, 98, 236, 0.05);
|
|
|
|
&:after {
|
|
content: '';
|
|
position: absolute;
|
|
bottom: 0;
|
|
width: 30%;
|
|
height: 6rpx;
|
|
background: #42D3AA;
|
|
border-radius: 3rpx 3rpx 0 0;
|
|
}
|
|
}
|
|
|
|
.tab-icon {
|
|
font-size: 40rpx;
|
|
margin-bottom: 6rpx;
|
|
}
|
|
|
|
.tab-text {
|
|
font-size: 28rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 连续核销开关
|
|
.continuous-switch {
|
|
margin: 20rpx auto;
|
|
width: 90%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-start;
|
|
}
|
|
|
|
// 扫码模式样式
|
|
.scan-mode-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
margin-top: 60rpx;
|
|
|
|
.scan-hexagon {
|
|
position: relative;
|
|
width: 300rpx;
|
|
height: 300rpx;
|
|
margin: 40rpx 0;
|
|
|
|
.scan-inner {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: #42D3AA;
|
|
border-radius: 40rpx;
|
|
box-shadow: 0 15rpx 30rpx rgba(166, 211, 170, 0.3), inset 0 -10rpx 15rpx rgba(0, 0, 0, 0.1);
|
|
z-index: 2;
|
|
transition: all 0.3s;
|
|
|
|
&:before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: linear-gradient(135deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 60%);
|
|
border-radius: 40rpx;
|
|
}
|
|
|
|
&.scanning {
|
|
transform: scale(0.95);
|
|
}
|
|
|
|
.scan-icon {
|
|
font-size: 100rpx;
|
|
color: white;
|
|
margin-bottom: 20rpx;
|
|
filter: drop-shadow(0 2rpx 4rpx rgba(0, 0, 0, 0.2));
|
|
z-index: 3;
|
|
}
|
|
|
|
.scan-lines {
|
|
position: relative;
|
|
width: 60%;
|
|
height: 60rpx;
|
|
overflow: hidden;
|
|
z-index: 3;
|
|
|
|
.scan-line {
|
|
position: absolute;
|
|
width: 100%;
|
|
height: 2rpx;
|
|
background: rgba(255, 255, 255, 0.8);
|
|
animation: scanMove 1.5s infinite ease-in-out;
|
|
|
|
&:nth-child(1) {
|
|
animation-delay: 0s;
|
|
top: 0;
|
|
}
|
|
|
|
&:nth-child(2) {
|
|
animation-delay: 0.5s;
|
|
top: 50%;
|
|
}
|
|
|
|
&:nth-child(3) {
|
|
animation-delay: 1s;
|
|
top: 100%;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.hexagon-overlay {
|
|
position: absolute;
|
|
top: -10rpx;
|
|
left: -10rpx;
|
|
width: calc(100% + 20rpx);
|
|
height: calc(100% + 20rpx);
|
|
background: transparent;
|
|
border: 2rpx solid rgba(118, 98, 236, 0.3);
|
|
border-radius: 45rpx;
|
|
z-index: 1;
|
|
animation: pulse 2s infinite;
|
|
}
|
|
|
|
&:after {
|
|
content: '';
|
|
position: absolute;
|
|
top: -20rpx;
|
|
left: -20rpx;
|
|
width: calc(100% + 40rpx);
|
|
height: calc(100% + 40rpx);
|
|
background: transparent;
|
|
border: 2rpx solid rgba(118, 98, 236, 0.2);
|
|
border-radius: 50rpx;
|
|
z-index: 0;
|
|
animation: pulse 2s infinite 1s;
|
|
}
|
|
}
|
|
|
|
.scan-prompt {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
margin-top: 40rpx;
|
|
|
|
.prompt-text {
|
|
font-size: 32rpx;
|
|
color: #333;
|
|
margin-bottom: 10rpx;
|
|
}
|
|
|
|
.sub-prompt {
|
|
font-size: 24rpx;
|
|
color: #42D3AA;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 手动输入模式样式
|
|
.input-mode-container {
|
|
margin: 60rpx auto;
|
|
width: 90%;
|
|
|
|
.input-card {
|
|
background: white;
|
|
border-radius: 20rpx;
|
|
padding: 40rpx 30rpx;
|
|
box-shadow: 0 10rpx 30rpx rgba(118, 98, 236, 0.08);
|
|
|
|
.input-title {
|
|
font-size: 34rpx;
|
|
color: #333;
|
|
margin-bottom: 30rpx;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.verify-button-view {
|
|
display: flex;
|
|
justify-content: center;
|
|
|
|
.verify-button {
|
|
margin-top: 40rpx;
|
|
background: #42D3AA;
|
|
border: none;
|
|
height: 90rpx;
|
|
font-size: 32rpx;
|
|
border-radius: 45rpx;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// 核销记录区域
|
|
.records-section {
|
|
margin: 60rpx auto 0;
|
|
width: 90%;
|
|
|
|
.section-title {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 20rpx;
|
|
|
|
.title-icon {
|
|
font-size: 40rpx;
|
|
color: #42D3AA;
|
|
margin-right: 10rpx;
|
|
}
|
|
|
|
.title-text {
|
|
font-size: 34rpx;
|
|
color: #333;
|
|
font-weight: 500;
|
|
}
|
|
}
|
|
|
|
.records-list {
|
|
.record-card {
|
|
background: white;
|
|
border-radius: 16rpx;
|
|
padding: 25rpx 30rpx;
|
|
margin-bottom: 20rpx;
|
|
box-shadow: 0 5rpx 15rpx rgba(0, 0, 0, 0.05);
|
|
|
|
.record-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 15rpx;
|
|
|
|
.order-number {
|
|
font-size: 30rpx;
|
|
color: #333;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.status-badge {
|
|
font-size: 24rpx;
|
|
color: #07c160;
|
|
background: rgba(7, 193, 96, 0.1);
|
|
padding: 4rpx 20rpx;
|
|
border-radius: 30rpx;
|
|
}
|
|
}
|
|
|
|
.record-time {
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.time-icon {
|
|
font-size: 28rpx;
|
|
color: #999;
|
|
margin-right: 8rpx;
|
|
}
|
|
|
|
.time-text {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 空状态样式
|
|
.empty-state {
|
|
margin-top: 100rpx;
|
|
}
|
|
|
|
// 商品确认弹窗样式
|
|
.confirm-popup {
|
|
.popup-header {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 30rpx;
|
|
border-bottom: 2rpx solid rgba(0, 0, 0, 0.05);
|
|
|
|
.check-icon {
|
|
font-size: 42rpx;
|
|
color: #42D3AA;
|
|
margin-right: 10rpx;
|
|
}
|
|
|
|
.header-title {
|
|
font-size: 32rpx;
|
|
color: #333;
|
|
font-weight: 500;
|
|
}
|
|
}
|
|
|
|
.popup-scroll {
|
|
/* #ifdef MP-WEIXIN */
|
|
max-height: calc(80vh - 280rpx);
|
|
/* #endif */
|
|
/* #ifdef APP-PLUS || H5 */
|
|
max-height: calc(80vh - 380rpx);
|
|
/* #endif */
|
|
}
|
|
|
|
.popup-content {
|
|
padding-bottom: 30rpx;
|
|
|
|
.product-card {
|
|
position: relative;
|
|
padding: 30rpx;
|
|
|
|
.product-main {
|
|
display: flex;
|
|
|
|
.product-image-container {
|
|
position: relative;
|
|
width: 180rpx;
|
|
height: 180rpx;
|
|
border-radius: 12rpx;
|
|
overflow: hidden;
|
|
|
|
.product-img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
|
|
.zoom-overlay {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: rgba(0, 0, 0, 0.3);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
opacity: 0;
|
|
transition: opacity 0.3s;
|
|
|
|
&:active {
|
|
opacity: 1;
|
|
}
|
|
|
|
.zoom-icon {
|
|
font-size: 44rpx;
|
|
color: white;
|
|
}
|
|
}
|
|
}
|
|
|
|
.product-details {
|
|
flex: 1;
|
|
margin-left: 20rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
|
|
.product-name {
|
|
font-size: 30rpx;
|
|
color: #333;
|
|
font-weight: 500;
|
|
margin-bottom: 10rpx;
|
|
}
|
|
|
|
.product-spec {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.product-quantity {
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.quantity-label {
|
|
font-size: 26rpx;
|
|
color: #666;
|
|
margin-right: 10rpx;
|
|
}
|
|
|
|
.quantity-value {
|
|
font-size: 36rpx;
|
|
color: #42D3AA;
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.product-divider {
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 30rpx;
|
|
right: 30rpx;
|
|
height: 2rpx;
|
|
background: rgba(0, 0, 0, 0.05);
|
|
}
|
|
}
|
|
|
|
.order-details {
|
|
margin-top: 30rpx;
|
|
padding: 0 30rpx;
|
|
|
|
.details-title {
|
|
font-size: 32rpx;
|
|
color: #333;
|
|
font-weight: 500;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.details-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr);
|
|
gap: 20rpx;
|
|
|
|
.detail-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-around;
|
|
background: #f8f7fe;
|
|
padding: 20rpx 15rpx;
|
|
border-radius: 12rpx;
|
|
|
|
.detail-icon {
|
|
font-size: 36rpx;
|
|
color: #42D3AA;
|
|
margin-right: 10rpx;
|
|
}
|
|
|
|
.detail-content {
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.detail-label {
|
|
font-size: 24rpx;
|
|
color: #666;
|
|
display: block;
|
|
margin-bottom: 5rpx;
|
|
}
|
|
}
|
|
|
|
.detail-value {
|
|
font-size: 24rpx;
|
|
color: #333;
|
|
display: block;
|
|
margin-top: 6rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.popup-footer {
|
|
padding: 30rpx;
|
|
// padding-bottom: calc(30rpx + constant(safe-area-inset-bottom));
|
|
// padding-bottom: calc(30rpx + env(safe-area-inset-bottom));
|
|
background: #fff;
|
|
border-top: 2rpx solid rgba(0, 0, 0, 0.05);
|
|
|
|
.confirm-button {
|
|
background: #42D3AA;
|
|
border: none;
|
|
height: 90rpx;
|
|
font-size: 32rpx;
|
|
border-radius: 45rpx;
|
|
}
|
|
|
|
.cancel-text {
|
|
text-align: center;
|
|
font-size: 28rpx;
|
|
color: #999;
|
|
margin-top: 20rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 自定义输入框样式
|
|
.custom-input {
|
|
border-radius: 45rpx;
|
|
overflow: hidden;
|
|
background: #f8f7fe;
|
|
}
|
|
|
|
// 动画效果
|
|
@keyframes scanMove {
|
|
0% {
|
|
transform: translateY(-100%);
|
|
opacity: 0;
|
|
}
|
|
|
|
50% {
|
|
opacity: 1;
|
|
}
|
|
|
|
100% {
|
|
transform: translateY(100%);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@keyframes pulse {
|
|
0% {
|
|
opacity: 0.8;
|
|
transform: scale(1);
|
|
}
|
|
|
|
50% {
|
|
opacity: 0.4;
|
|
}
|
|
|
|
100% {
|
|
opacity: 0;
|
|
transform: scale(1.2);
|
|
}
|
|
}
|
|
|
|
// 修复样式嵌套问题
|
|
::v-deep .wd-switch {
|
|
height: 50rpx !important;
|
|
width: 90rpx !important;
|
|
font-size: 22px !important;
|
|
}
|
|
|
|
::v-deep .wd-status-tip__text {
|
|
margin: 0 auto !important;
|
|
}
|
|
</style> |