356 lines
10 KiB
Vue
356 lines
10 KiB
Vue
<template>
|
|
<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="nav-bg-layer"></view>
|
|
|
|
<!-- 功能模式切换和连续核销开关 -->
|
|
<view class=" li-w-92% li-mx-auto li-flex li-justify-between li-items-center li-mt-20">
|
|
<wd-tabs v-model="activeMode" :sticky="false" :line-width="18" line-height="4" active-color="#0070F0">
|
|
<wd-tab title="入库核销"></wd-tab>
|
|
<wd-tab title="手动输入"></wd-tab>
|
|
</wd-tabs>
|
|
</view>
|
|
|
|
<view class="li-w-90% li-mx-auto li-mt-50 li-flex li-items-center">
|
|
<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="#0070F0" size="24" />
|
|
</view>
|
|
|
|
<!-- 功能区域 - 根据当前模式显示不同内容 -->
|
|
<view class="li-w-92% li-mx-auto li-mt-40">
|
|
<!-- 扫码模式 -->
|
|
<view v-if="activeMode === 0" class=" li-flex li-flex-col li-items-center">
|
|
<view class="scan-button-wrapper li-mt-50" @click="scanCode">
|
|
<view class="scan-button li-flex li-items-center li-justify-center">
|
|
<text class="ri-qr-scan-2-line li-text-90"></text>
|
|
</view>
|
|
</view>
|
|
<view class="li-text-30 li-text-#666 li-mt-30">点击扫描二维码入库核销</view>
|
|
<view class="li-text-24 li-text-#999 li-mt-10">{{continuousMode ? '连续核销模式已开启' : ''}}</view>
|
|
</view>
|
|
|
|
<!-- 手动输入模式 -->
|
|
<view v-else class="input-mode-container">
|
|
<view class="li-bg-white li-rd-20 li-px-30 li-py-40 li-shadow-sm li-mt-30">
|
|
<view class="li-text-32 li-mb-30 li-text-#333">请输入订单号</view>
|
|
<wd-input v-model="orderNumber" placeholder="请输入需要核销的订单号" clear-able />
|
|
<view class="li-flex li-justify-center li-mt-30">
|
|
<wd-button type="primary" @click="submitOrderNumber" block>立即核销</wd-button>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 连续核销模式下的结果展示区域 -->
|
|
<view v-if="verificationRecords.length > 0" class="verification-records li-w-92% li-mx-auto li-mt-40">
|
|
<view class="li-text-34 li-text-#333 li-mb-20">最近核销记录</view>
|
|
|
|
<view class="records-list">
|
|
<view v-for="(record, index) in verificationRecords" :key="index"
|
|
class="record-item li-flex li-items-center li-justify-between li-bg-white li-rd-20 li-px-30 li-py-25 li-mb-20 li-shadow-sm">
|
|
<view class="li-flex li-flex-col">
|
|
<view class="li-flex li-items-center">
|
|
<text class="ri-file-list-3-line li-mr-10 li-text-#0070F0"></text>
|
|
<text class="li-text-30">{{record.orderNumber}}</text>
|
|
</view>
|
|
<text class="li-text-24 li-text-#999 li-mt-8">{{record.time}}</text>
|
|
</view>
|
|
<view class="status-badge" :class="[
|
|
record.status === 'success' ? 'status-success' :
|
|
record.status === 'fail' ? 'status-fail' : 'status-pending'
|
|
]">
|
|
{{record.status === 'success' ? '核销成功' :
|
|
record.status === 'fail' ? '核销失败' : '处理中'}}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 空状态提示 -->
|
|
<view v-if="verificationRecords.length === 0"
|
|
class="empty-state li-w-92% li-mx-auto li-mt-60 li-flex li-flex-col li-items-center">
|
|
<text class="ri-inbox-line li-text-100 li-text-#ddd"></text>
|
|
<view class="li-text-30 li-text-#999 li-mt-20">暂无核销记录</view>
|
|
</view>
|
|
|
|
|
|
<!-- 顶部提示条(成功/失败消息提示) -->
|
|
<wd-toast />
|
|
</view>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, reactive } from 'vue'
|
|
import { onLoad } from '@dcloudio/uni-app'
|
|
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 verificationRecords = ref([
|
|
// 示例数据,实际应为空数组
|
|
{
|
|
orderNumber: 'JD202503050001',
|
|
time: '2025-03-05 21:58:34',
|
|
status: 'success' // success, fail, pending
|
|
}
|
|
])
|
|
|
|
// 扫码核销
|
|
const scanCode = () => {
|
|
uni.scanCode({
|
|
success: (res) => {
|
|
handleVerification(res.result)
|
|
},
|
|
fail: (err) => {
|
|
Toast.error('扫码失败,请重试')
|
|
}
|
|
})
|
|
}
|
|
|
|
// 提交订单号核销
|
|
const submitOrderNumber = () => {
|
|
if (!orderNumber.value) {
|
|
Toast.error('请输入订单号')
|
|
return
|
|
}
|
|
handleVerification(orderNumber.value)
|
|
orderNumber.value = '' // 清空输入
|
|
}
|
|
|
|
// 处理核销逻辑
|
|
const handleVerification = (code : string) => {
|
|
// 模拟核销处理过程
|
|
// 实际项目中这里应该调用API进行核销
|
|
|
|
// 模拟API调用延迟
|
|
if (continuousMode.value) {
|
|
// 添加一条处理中的记录
|
|
const newRecord = {
|
|
orderNumber: code,
|
|
time: formatDateTime(new Date()),
|
|
status: 'pending'
|
|
}
|
|
verificationRecords.value.unshift(newRecord)
|
|
|
|
// 模拟API请求处理时间
|
|
setTimeout(() => {
|
|
// 模拟随机结果 (实际项目中应根据API响应决定)
|
|
const isSuccess = Math.random() > 0.2 // 80%概率成功
|
|
|
|
// 更新记录状态
|
|
const record = verificationRecords.value.find(r => r.orderNumber === code && r.status === 'pending')
|
|
if (record) {
|
|
record.status = isSuccess ? 'success' : 'fail'
|
|
}
|
|
|
|
// 显示结果提示
|
|
Toast[isSuccess ? 'success' : 'fail'](isSuccess ? '核销成功' : '核销失败')
|
|
}, 800)
|
|
} else {
|
|
// 非连续模式 - 直接跳转到详情页
|
|
Toast.loading('核销中...')
|
|
|
|
// 模拟API请求
|
|
setTimeout(() => {
|
|
Toast.close()
|
|
// 这里应该根据实际API响应决定是否跳转
|
|
// 模拟80%概率成功
|
|
if (Math.random() > 0.2) {
|
|
// 跳转到详情页,传递订单号参数
|
|
uni.navigateTo({
|
|
url: `/pagesA/verification/detail?orderNumber=${code}`
|
|
})
|
|
} else {
|
|
Toast.error('核销失败,请重试')
|
|
}
|
|
}, 800)
|
|
}
|
|
}
|
|
|
|
// 格式化日期时间
|
|
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'
|
|
// })
|
|
}
|
|
|
|
// 页面跳转
|
|
const toPages = (item : any) => {
|
|
if (item.type === 'nav') {
|
|
uni.navigateBack()
|
|
} else if (item.type === 'home') {
|
|
// 这里是项目内部的跳转逻辑
|
|
uni.switchTab({
|
|
url: '/pages/index/index'
|
|
})
|
|
}
|
|
}
|
|
|
|
onLoad(() => {
|
|
checkRouteStack()
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
page {
|
|
background-color: #f7f8fc;
|
|
}
|
|
|
|
.verification-page {
|
|
|
|
// 导航背景层
|
|
.nav-bg-layer {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: calc(var(--status-bar-height) + 88rpx);
|
|
background: linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.9) 100%);
|
|
z-index: -1;
|
|
backdrop-filter: blur(10px);
|
|
-webkit-backdrop-filter: blur(10px);
|
|
}
|
|
|
|
// 扫码功能区
|
|
.scan-button-wrapper {
|
|
width: 300rpx;
|
|
height: 300rpx;
|
|
position: relative;
|
|
|
|
.scan-button {
|
|
width: 100%;
|
|
height: 100%;
|
|
background: linear-gradient(135deg, #42a5ff 0%, #0070F0 100%);
|
|
border-radius: 50%;
|
|
box-shadow: 0 8rpx 30rpx rgba(56, 165, 255, 0.25);
|
|
color: white;
|
|
transition: all 0.3s ease;
|
|
|
|
&:active {
|
|
transform: scale(0.95);
|
|
box-shadow: 0 4rpx 15rpx rgba(56, 165, 255, 0.2);
|
|
}
|
|
}
|
|
|
|
&::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: -10rpx;
|
|
left: -10rpx;
|
|
right: -10rpx;
|
|
bottom: -10rpx;
|
|
border-radius: 50%;
|
|
border: 2rpx solid rgba(56, 165, 255, 0.2);
|
|
z-index: -1;
|
|
}
|
|
}
|
|
|
|
// 核销记录状态标签
|
|
.status-badge {
|
|
padding: 4rpx 20rpx;
|
|
border-radius: 30rpx;
|
|
font-size: 24rpx;
|
|
|
|
&.status-success {
|
|
color: #07c160;
|
|
background-color: rgba(7, 193, 96, 0.1);
|
|
}
|
|
|
|
&.status-fail {
|
|
color: #fa5151;
|
|
background-color: rgba(250, 81, 81, 0.1);
|
|
}
|
|
|
|
&.status-pending {
|
|
color: #f0ad4e;
|
|
background-color: rgba(240, 173, 78, 0.1);
|
|
}
|
|
}
|
|
|
|
// 卡片阴影效果
|
|
.li-shadow-sm {
|
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
|
}
|
|
|
|
// 输入模式美化
|
|
.input-mode-container {
|
|
.wd-button {
|
|
border-radius: 10rpx;
|
|
height: 90rpx;
|
|
font-size: 32rpx;
|
|
}
|
|
}
|
|
|
|
// 底部区域间距
|
|
.empty-state {
|
|
padding-bottom: 40rpx;
|
|
}
|
|
}
|
|
|
|
::v-deep .wd-switch {
|
|
height: 50rpx !important;
|
|
width: 90rpx !important;
|
|
font-size: 22px !important;
|
|
}
|
|
</style> |