forked from gxwebsoft/mp-10550
refactor(api): 更新 API调用以使用新的请求工具- 将所有 API 调用中的 request-legacy 替换为 request
- 优化部分 API 调用的参数传递方式 - 统一导入 ApiResult 和 PageResult 类型的路径
This commit is contained in:
@@ -169,7 +169,7 @@ const GiftCardDetail = () => {
|
||||
<View className="flex items-center justify-between mb-4">
|
||||
<View className="w-full">
|
||||
<Text className="text-4xl font-bold">{getGiftValueDisplay()}</Text>
|
||||
<Text className="text-lg opacity-90 mt-1">{getGiftTypeText(gift.type)}</Text>
|
||||
<Text className="opacity-90 mt-1 px-2">{getGiftTypeText(gift.type)}</Text>
|
||||
</View>
|
||||
<View
|
||||
className="p-2 bg-white bg-opacity-20 rounded-lg cursor-pointer"
|
||||
@@ -263,12 +263,12 @@ const GiftCardDetail = () => {
|
||||
</>
|
||||
)}
|
||||
|
||||
{gift.useTime && (
|
||||
{gift.takeTime && (
|
||||
<>
|
||||
<Divider />
|
||||
<View>
|
||||
<Text className="text-gray-600 text-sm mb-2">使用记录</Text>
|
||||
<Text className="text-gray-900">使用时间:{dayjs(gift.useTime).format('YYYY-MM-DD HH:mm')}</Text>
|
||||
<Text className="text-gray-900">使用时间:{dayjs(gift.takeTime).format('YYYY-MM-DD HH:mm')}</Text>
|
||||
</View>
|
||||
</>
|
||||
)}
|
||||
@@ -323,7 +323,7 @@ const GiftCardDetail = () => {
|
||||
<SimpleQRCodeModal
|
||||
visible={showQRCode}
|
||||
onClose={() => setShowQRCode(false)}
|
||||
qrContent={gift.code || ''}
|
||||
qrContent={gift.code + ''}
|
||||
giftName={gift.goodsName || gift.name}
|
||||
faceValue={gift.faceValue}
|
||||
/>
|
||||
|
||||
@@ -20,7 +20,7 @@ const GiftCardManage = () => {
|
||||
// const [showRedeemModal, setShowRedeemModal] = useState(false)
|
||||
// const [filters, setFilters] = useState({
|
||||
// type: [] as number[],
|
||||
// sortBy: 'createTime' as 'createTime' | 'expireTime' | 'faceValue' | 'useTime',
|
||||
// sortBy: 'createTime' as 'createTime' | 'expireTime' | 'faceValue' | 'takeTime',
|
||||
// sortOrder: 'desc' as 'asc' | 'desc'
|
||||
// })
|
||||
|
||||
@@ -175,7 +175,7 @@ const GiftCardManage = () => {
|
||||
type: gift.type,
|
||||
status: gift.status,
|
||||
expireTime: gift.expireTime,
|
||||
useTime: gift.useTime,
|
||||
takeTime: gift.takeTime,
|
||||
useLocation: gift.useLocation,
|
||||
contactInfo: gift.contactInfo,
|
||||
// 添加商品信息
|
||||
|
||||
@@ -137,7 +137,7 @@ const GiftCardRedeem = () => {
|
||||
faceValue: gift.faceValue,
|
||||
type: gift.type,
|
||||
expireTime: gift.expireTime,
|
||||
useTime: gift.useTime,
|
||||
takeTime: gift.takeTime,
|
||||
useLocation: gift.useLocation,
|
||||
contactInfo: gift.contactInfo,
|
||||
showCode: false, // 兑换页面不显示兑换码
|
||||
|
||||
@@ -128,7 +128,7 @@ const GiftCardUse = () => {
|
||||
faceValue: gift.faceValue,
|
||||
type: gift.type,
|
||||
expireTime: gift.expireTime,
|
||||
useTime: gift.useTime,
|
||||
takeTime: gift.takeTime,
|
||||
useLocation: gift.useLocation,
|
||||
contactInfo: gift.contactInfo,
|
||||
showCode: false,
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import React, { useState } from 'react'
|
||||
import React, {useState} from 'react'
|
||||
import {View, Text, Image} from '@tarojs/components'
|
||||
import {Button, Input, Tag, Divider} from '@nutui/nutui-react-taro'
|
||||
import {Button, Input} from '@nutui/nutui-react-taro'
|
||||
import {Scan, Search} from '@nutui/icons-react-taro'
|
||||
import Taro from '@tarojs/taro'
|
||||
import dayjs from 'dayjs'
|
||||
import {getShopGiftByCode, updateShopGift} from "@/api/shop/shopGift";
|
||||
import {getShopGiftByCode, updateShopGift, decryptQrData} from "@/api/shop/shopGift";
|
||||
import {useUser} from "@/hooks/useUser";
|
||||
import type { ShopGift } from "@/api/shop/shopGift/model";
|
||||
import type {ShopGift} from "@/api/shop/shopGift/model";
|
||||
import {isValidJSON} from "@/utils/jsonUtils";
|
||||
|
||||
const StoreVerification: React.FC = () => {
|
||||
const {
|
||||
@@ -15,7 +16,6 @@ const StoreVerification: React.FC = () => {
|
||||
const [scanResult, setScanResult] = useState<string>('')
|
||||
const [verificationCode, setVerificationCode] = useState<string>('')
|
||||
const [giftInfo, setGiftInfo] = useState<ShopGift | null>(null)
|
||||
const [verificationResult, setVerificationResult] = useState<'success' | 'failed' | null>(null)
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
// 扫码功能
|
||||
@@ -23,9 +23,17 @@ const StoreVerification: React.FC = () => {
|
||||
Taro.scanCode({
|
||||
success: (res) => {
|
||||
if (res.result) {
|
||||
setScanResult(res.result)
|
||||
setVerificationCode(res.result)
|
||||
handleManualVerification(res.result)
|
||||
console.log('扫码结果:', res.result)
|
||||
|
||||
// 判断是否为JSON格式
|
||||
if (isValidJSON(res.result)) {
|
||||
setLoading(true)
|
||||
const json = JSON.parse(res.result)
|
||||
console.log(json, 'json')
|
||||
if (json.businessType === 'gift') {
|
||||
handleDecryptAndVerify(json.token, json.data).then()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
@@ -38,7 +46,23 @@ const StoreVerification: React.FC = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// 调用解密接口
|
||||
const handleDecryptAndVerify = async (token: string, encryptedData: string) => {
|
||||
const decryptedData = await decryptQrData({token, encryptedData})
|
||||
console.log('解密成功:', decryptedData)
|
||||
setScanResult(`${decryptedData}`)
|
||||
setVerificationCode(`${decryptedData}`)
|
||||
await handleVerification(`${decryptedData}`)
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
// 验证商品信息
|
||||
const handleVerification = async (code?: string) => {
|
||||
// 这里应该调用后端API验证核销码
|
||||
const gift = await getShopGiftByCode(`${code}`)
|
||||
// 设置礼品信息用于显示
|
||||
setGiftInfo(gift)
|
||||
}
|
||||
|
||||
// 手动输入核销码验证
|
||||
const handleManualVerification = async (code?: string) => {
|
||||
@@ -55,7 +79,6 @@ const StoreVerification: React.FC = () => {
|
||||
setGiftInfo(gift)
|
||||
|
||||
if (!isAdmin()) {
|
||||
setVerificationResult('failed')
|
||||
setLoading(false)
|
||||
return Taro.showToast({
|
||||
title: '您没有核销权限',
|
||||
@@ -63,7 +86,6 @@ const StoreVerification: React.FC = () => {
|
||||
})
|
||||
}
|
||||
if (gift.status === 1) {
|
||||
setVerificationResult('failed')
|
||||
setLoading(false)
|
||||
return Taro.showToast({
|
||||
title: '此礼品码已使用',
|
||||
@@ -71,7 +93,6 @@ const StoreVerification: React.FC = () => {
|
||||
})
|
||||
}
|
||||
if (gift.status === 2) {
|
||||
setVerificationResult('failed')
|
||||
setLoading(false)
|
||||
return Taro.showToast({
|
||||
title: '此礼品码已失效',
|
||||
@@ -79,7 +100,6 @@ const StoreVerification: React.FC = () => {
|
||||
})
|
||||
}
|
||||
if (gift.userId === 0) {
|
||||
setVerificationResult('failed')
|
||||
setLoading(false)
|
||||
return Taro.showToast({
|
||||
title: '此礼品码未认领',
|
||||
@@ -88,7 +108,6 @@ const StoreVerification: React.FC = () => {
|
||||
}
|
||||
|
||||
// 验证成功,设置状态
|
||||
setVerificationResult('success')
|
||||
await updateShopGift({
|
||||
...gift,
|
||||
status: 1,
|
||||
@@ -106,7 +125,6 @@ const StoreVerification: React.FC = () => {
|
||||
}, 2000)
|
||||
} catch (error) {
|
||||
console.error('验证失败:', error)
|
||||
setVerificationResult('failed')
|
||||
Taro.showToast({
|
||||
title: '验证失败',
|
||||
icon: 'error'
|
||||
@@ -121,7 +139,6 @@ const StoreVerification: React.FC = () => {
|
||||
setScanResult('')
|
||||
setVerificationCode('')
|
||||
setGiftInfo(null)
|
||||
setVerificationResult(null)
|
||||
}
|
||||
|
||||
// 获取类型文本
|
||||
@@ -169,159 +186,124 @@ const StoreVerification: React.FC = () => {
|
||||
扫描二维码
|
||||
</Button>
|
||||
|
||||
{/* 扫码结果显示 */}
|
||||
{scanResult && !giftInfo && (
|
||||
<View className="mt-3 p-3 bg-gray-50 rounded">
|
||||
<Text className="text-sm text-gray-600">扫码结果:</Text>
|
||||
<Text className="text-xs text-gray-500 break-all mt-1">
|
||||
{scanResult}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* 商品信息展示 */}
|
||||
{giftInfo && (
|
||||
<View className="mt-4 p-4 bg-white rounded-lg shadow-sm border border-gray-100">
|
||||
<View className="flex items-center mb-3">
|
||||
<Text className="text-lg font-semibold text-gray-800">商品信息</Text>
|
||||
<View className={`ml-2 px-2 py-1 rounded text-xs ${
|
||||
giftInfo.status === 0 ? 'bg-green-100 text-green-600' :
|
||||
giftInfo.status === 1 ? 'bg-gray-100 text-gray-600' :
|
||||
'bg-red-100 text-red-600'
|
||||
}`}>
|
||||
{giftInfo.status === 0 ? '未使用' :
|
||||
giftInfo.status === 1 ? '已使用' : '已过期'}
|
||||
</View>
|
||||
{/* 手动输入区域 */}
|
||||
<View className="mt-8"></View>
|
||||
<View className="font-bold mb-3">手动输入核销码</View>
|
||||
<View className="flex items-center justify-between">
|
||||
<Input
|
||||
placeholder="请输入6位核销码"
|
||||
value={verificationCode}
|
||||
onChange={setVerificationCode}
|
||||
maxLength={6}
|
||||
className="flex-1 mr-8"
|
||||
style={{
|
||||
backgroundColor: '#f3f3f3',
|
||||
borderRadius: '8px'
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<Search/>}
|
||||
loading={loading}
|
||||
onClick={() => handleVerification(verificationCode)}
|
||||
>
|
||||
验证
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
|
||||
{/*在扫码结果显示区域添加解密状态提示*/}
|
||||
{scanResult && !giftInfo && (
|
||||
<View className="mt-4 p-4 bg-gray-50 rounded-lg">
|
||||
<Text className="text-sm text-gray-600">
|
||||
{loading ? '正在解密验证...' : '扫码结果:'}
|
||||
</Text>
|
||||
<Text className="text-xs text-gray-500 break-all mt-1">
|
||||
{scanResult}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* 商品信息展示 */}
|
||||
{giftInfo && (
|
||||
<View className="mt-4 mx-4 p-4 bg-white rounded-lg shadow-sm border border-gray-100">
|
||||
<View className="flex items-center mb-3">
|
||||
<Text className="text-lg font-semibold text-gray-800">商品信息</Text>
|
||||
<View className={`ml-2 px-2 py-1 rounded text-xs ${
|
||||
giftInfo.status === 0 ? 'bg-green-100 text-green-600' :
|
||||
giftInfo.status === 1 ? 'bg-gray-100 text-gray-600' :
|
||||
'bg-red-100 text-red-600'
|
||||
}`}>
|
||||
{giftInfo.status === 0 ? '未使用' :
|
||||
giftInfo.status === 1 ? '已使用' : '已过期'}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className="flex">
|
||||
{/* 商品图片 */}
|
||||
{giftInfo.goodsImage && (
|
||||
<View className="w-20 h-20 mr-3 flex-shrink-0">
|
||||
<Image
|
||||
src={giftInfo.goodsImage}
|
||||
className="w-full h-full rounded-lg object-cover border border-gray-200"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
<View className="mt-3 pt-3 border-t border-gray-100 flex justify-between">
|
||||
{/* 商品图片 */}
|
||||
{giftInfo.goodsImage && (
|
||||
<View className="w-20 h-20 mr-3 flex-shrink-0">
|
||||
<Image
|
||||
src={giftInfo.goodsImage}
|
||||
className="w-full h-full rounded-lg object-cover border border-gray-200"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* 商品详情 */}
|
||||
<View className="flex-1">
|
||||
<Text className="text-base font-medium text-gray-900 mb-1">
|
||||
{giftInfo.goodsName || giftInfo.name}
|
||||
</Text>
|
||||
|
||||
{giftInfo.description && (
|
||||
<Text className="text-sm text-gray-600 mb-2" style={{
|
||||
{/* 商品详情 */}
|
||||
<View className="flex-1">
|
||||
<View className="text-base font-medium text-gray-900 mb-1">
|
||||
{giftInfo.goodsName || giftInfo.name}
|
||||
</View>
|
||||
<View className="text-sm text-gray-400">
|
||||
使用门店:{giftInfo.useLocation || '123123'}
|
||||
</View>
|
||||
{giftInfo.description && (
|
||||
<>
|
||||
<View className="text-sm text-gray-600 mb-2" style={{
|
||||
display: '-webkit-box',
|
||||
WebkitLineClamp: 2,
|
||||
WebkitBoxOrient: 'vertical',
|
||||
overflow: 'hidden'
|
||||
}}>
|
||||
{giftInfo.description}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
</>
|
||||
)}
|
||||
|
||||
<View className="flex items-center justify-between">
|
||||
<Text className="text-lg font-bold text-red-500">
|
||||
¥{giftInfo.faceValue}
|
||||
</Text>
|
||||
<Text className="text-xs text-gray-500">
|
||||
{giftInfo.type === 10 ? '实物礼品' :
|
||||
giftInfo.type === 20 ? '虚拟礼品' : '服务礼品'}
|
||||
</Text>
|
||||
</View>
|
||||
<View className="flex items-center justify-between">
|
||||
<Text className="text-lg font-bold text-red-500">
|
||||
¥{giftInfo.faceValue}
|
||||
</Text>
|
||||
<Text className="text-xs text-gray-500">
|
||||
{giftInfo.type === 10 ? '实物礼品' :
|
||||
giftInfo.type === 20 ? '虚拟礼品' : '服务礼品'}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 附加信息 */}
|
||||
<View className="mt-3 pt-3 border-t border-gray-100">
|
||||
{giftInfo.useLocation && (
|
||||
<View className="flex items-center mb-2">
|
||||
<Text className="text-sm text-gray-600 w-16">使用门店:</Text>
|
||||
<Text className="text-sm text-gray-800 flex-1">{giftInfo.useLocation}</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{giftInfo.expireTime && (
|
||||
<View className="flex items-center mb-2">
|
||||
<Text className="text-sm text-gray-600 w-16">有效期至:</Text>
|
||||
<Text className="text-sm text-gray-800">
|
||||
{dayjs(giftInfo.expireTime).format('YYYY-MM-DD HH:mm')}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{giftInfo.contactInfo && (
|
||||
<View className="flex items-center">
|
||||
<Text className="text-sm text-gray-600 w-16">客服电话:</Text>
|
||||
<Text className="text-sm text-blue-600">{giftInfo.contactInfo}</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
||||
{/* 手动输入区域 */}
|
||||
{
|
||||
!giftInfo && (
|
||||
<View className="bg-white mx-4 mt-4 p-4 rounded-lg">
|
||||
<Text className="font-bold mb-3">手动输入核销码</Text>
|
||||
<View className="flex">
|
||||
<Input
|
||||
placeholder="请输入6位核销码"
|
||||
value={verificationCode}
|
||||
onChange={setVerificationCode}
|
||||
maxLength={6}
|
||||
className="flex-1 mr-2"
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<Search/>}
|
||||
loading={loading}
|
||||
onClick={() => handleManualVerification(verificationCode)}
|
||||
>
|
||||
验证
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
{/* 附加信息 */}
|
||||
<View className="mt-3 pt-3 border-t border-gray-100">
|
||||
|
||||
|
||||
{/* 礼品卡信息 */}
|
||||
{giftInfo && (
|
||||
<View className="bg-white mx-4 mt-4 p-4 rounded-lg">
|
||||
<View className="flex justify-between items-center mb-3">
|
||||
<Text className="font-bold">礼品卡信息</Text>
|
||||
{verificationResult === 'success' && (
|
||||
<Tag type="success">
|
||||
验证成功
|
||||
</Tag>
|
||||
{giftInfo.expireTime && (
|
||||
<View className="flex items-center mb-2">
|
||||
<Text className="text-sm text-gray-600">有效期至:</Text>
|
||||
<Text className="text-sm text-gray-800">
|
||||
{dayjs(giftInfo.expireTime).format('YYYY-MM-DD HH:mm')}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
{verificationResult === 'failed' && (
|
||||
<Tag type="danger">
|
||||
验证失败
|
||||
</Tag>
|
||||
|
||||
{giftInfo.contactInfo && (
|
||||
<View className="flex items-center">
|
||||
<Text className="text-sm text-gray-600">客服电话:</Text>
|
||||
<Text className="text-sm text-blue-600">{giftInfo.contactInfo}</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<View>
|
||||
<View className="flex justify-between mb-3">
|
||||
<Text className="text-gray-600">商品名称</Text>
|
||||
<Text className="font-medium">
|
||||
{giftInfo.goodsName || giftInfo.name}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View className="flex justify-between mb-3">
|
||||
<Text className="text-gray-600">面值</Text>
|
||||
<Text className="text-lg font-bold text-red-500">
|
||||
¥{giftInfo.faceValue}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View className="flex justify-between mb-3">
|
||||
<Text className="text-gray-600">类型</Text>
|
||||
@@ -333,34 +315,37 @@ const StoreVerification: React.FC = () => {
|
||||
<Text className="font-mono text-sm">{giftInfo.code}</Text>
|
||||
</View>
|
||||
|
||||
{giftInfo.expireTime && (
|
||||
<View className="flex justify-between">
|
||||
<Text className="text-gray-600">有效期至</Text>
|
||||
<Text className="text-orange-600">
|
||||
{dayjs(giftInfo.expireTime).format('YYYY-MM-DD')}
|
||||
</Text>
|
||||
{giftInfo.operatorUserName && (
|
||||
<View className="flex justify-between mb-3">
|
||||
<Text className="text-gray-600">核销人员</Text>
|
||||
<Text className="font-mono text-sm">{giftInfo.operatorUserName}</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{giftInfo.takeTime && (
|
||||
<View className="flex justify-between mb-3">
|
||||
<Text className="text-gray-600">核销时间</Text>
|
||||
<Text className="font-mono text-sm">{giftInfo.takeTime}</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{giftInfo && giftInfo.status === 0 && (
|
||||
<Button
|
||||
size="large"
|
||||
type="info"
|
||||
loading={loading}
|
||||
onClick={() => handleManualVerification()}
|
||||
block
|
||||
>
|
||||
确认核销
|
||||
</Button>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<Divider/>
|
||||
|
||||
{giftInfo && (
|
||||
<Button
|
||||
size="large"
|
||||
type="primary"
|
||||
loading={loading}
|
||||
onClick={() => handleManualVerification()}
|
||||
block
|
||||
>
|
||||
确认核销
|
||||
</Button>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* 使用说明 */}
|
||||
<View className="bg-blue-50 mx-4 mb-4 p-4 rounded-lg">
|
||||
<View className="bg-blue-50 mx-4 my-4 p-4 rounded-lg">
|
||||
<Text className="font-bold mb-2 text-gray-500">操作说明:</Text>
|
||||
<View>
|
||||
<Text className="text-sm text-gray-500 mb-1">1. 用户出示礼品卡二维码</Text>
|
||||
@@ -369,6 +354,7 @@ const StoreVerification: React.FC = () => {
|
||||
<Text className="text-sm text-gray-500">4. 验证成功后点击"确认核销"完成</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View className={'h-10'}></View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user