diff --git a/package.json b/package.json index 9f594b7..e57ea99 100644 --- a/package.json +++ b/package.json @@ -63,18 +63,17 @@ "@tarojs/shared": "4.0.8", "@tarojs/taro": "4.0.8", "@tarojs/taro-rn": "^4.1.4", - "@types/qrcode": "^1.5.5", "crypto-js": "^4.2.0", "dayjs": "^1.11.13", "echarts-taro3-react": "^1.0.13", "expo": "~50.0.2", "js-base64": "^3.7.7", - "qrcode": "^1.5.4", "react": "^18.3.1", "react-dom": "^18.3.1", "react-markdown": "^10.1.0", "react-native": "^0.73.1", - "react-router-dom": "^7.1.1" + "react-router-dom": "^7.1.1", + "weapp-qrcode": "^1.0.0" }, "devDependencies": { "@babel/core": "^7.26.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 03bfddd..b4a357a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -86,9 +86,6 @@ importers: '@tarojs/taro-rn': specifier: ^4.1.4 version: 4.1.4(uta2iou7tmlqjr3423a7zge7su) - '@types/qrcode': - specifier: ^1.5.5 - version: 1.5.5 crypto-js: specifier: ^4.2.0 version: 4.2.0 @@ -104,9 +101,6 @@ importers: js-base64: specifier: ^3.7.7 version: 3.7.7 - qrcode: - specifier: ^1.5.4 - version: 1.5.4 react: specifier: ^18.3.1 version: 18.3.1 @@ -122,6 +116,9 @@ importers: react-router-dom: specifier: ^7.1.1 version: 7.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + weapp-qrcode: + specifier: ^1.0.0 + version: 1.0.0 devDependencies: '@babel/core': specifier: ^7.26.0 @@ -2718,9 +2715,6 @@ packages: '@types/prop-types@15.7.14': resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==, tarball: https://registry.npmmirror.com/@types/prop-types/-/prop-types-15.7.14.tgz} - '@types/qrcode@1.5.5': - resolution: {integrity: sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==} - '@types/qs@6.9.17': resolution: {integrity: sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==, tarball: https://registry.npmmirror.com/@types/qs/-/qs-6.9.17.tgz} @@ -9891,6 +9885,9 @@ packages: wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==, tarball: https://registry.npmmirror.com/wcwidth/-/wcwidth-1.0.1.tgz} + weapp-qrcode@1.0.0: + resolution: {integrity: sha512-4sa3W0rGDVJ9QaeZpAKlAuUxVyjhDwiUqHyGK/jJMsRMXnhb4yO8qWU/pZruMo+iT5J6CraS67lDMFb1VY+RaA==} + web-namespaces@2.0.1: resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} @@ -13679,10 +13676,6 @@ snapshots: '@types/prop-types@15.7.14': {} - '@types/qrcode@1.5.5': - dependencies: - '@types/node': 18.19.68 - '@types/qs@6.9.17': {} '@types/range-parser@1.2.7': {} @@ -22360,6 +22353,10 @@ snapshots: dependencies: defaults: 1.0.4 + weapp-qrcode@1.0.0: + dependencies: + extend: 3.0.2 + web-namespaces@2.0.1: {} webidl-conversions@3.0.1: {} diff --git a/src/app.config.ts b/src/app.config.ts index bbe79cf..a7641e1 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -43,7 +43,6 @@ export default defineAppConfig({ "gift/index", "gift/redeem", "gift/detail", - "gift/qrcode-demo", "store/verification" ] }, diff --git a/src/components/CouponShare.tsx b/src/components/CouponShare.tsx index 4339fe9..e3928d0 100644 --- a/src/components/CouponShare.tsx +++ b/src/components/CouponShare.tsx @@ -1,7 +1,7 @@ import React from 'react' import { View, Text } from '@tarojs/components' -import { Button, Popup } from '@nutui/nutui-react-taro' -import { Share, Wechat, QQ, Weibo, Link, Close } from '@nutui/icons-react-taro' +import { Popup } from '@nutui/nutui-react-taro' +import { Share, Link, Close } from '@nutui/icons-react-taro' import Taro from '@tarojs/taro' export interface CouponShareProps { @@ -28,10 +28,10 @@ const CouponShare: React.FC = ({ // 生成分享文案 const generateShareText = () => { const typeText = coupon.type === 10 ? '满减券' : coupon.type === 20 ? '折扣券' : '免费券' - const amountText = coupon.type === 10 ? `¥${coupon.amount}` : + const amountText = coupon.type === 10 ? `¥${coupon.amount}` : coupon.type === 20 ? `${coupon.amount}折` : '免费' const conditionText = coupon.minAmount ? `满${coupon.minAmount}元可用` : '无门槛' - + return `🎁 ${coupon.name}\n💰 ${amountText} ${typeText}\n📋 ${conditionText}\n快来领取吧!` } @@ -66,7 +66,7 @@ const CouponShare: React.FC = ({ const shareUrl = generateShareUrl() const shareText = generateShareText() const fullText = `${shareText}\n\n${shareUrl}` - + Taro.setClipboardData({ data: fullText, success: () => { @@ -104,7 +104,7 @@ const CouponShare: React.FC = ({ const shareOptions = [ { - icon: , + icon: , label: '微信好友', onClick: handleWechatShare }, @@ -142,7 +142,7 @@ const CouponShare: React.FC = ({ - {coupon.type === 10 ? `¥${coupon.amount}` : + {coupon.type === 10 ? `¥${coupon.amount}` : coupon.type === 20 ? `${coupon.amount}折` : '免费'} diff --git a/src/components/GiftCardQRCode.tsx b/src/components/GiftCardQRCode.tsx index d05885e..3745405 100644 --- a/src/components/GiftCardQRCode.tsx +++ b/src/components/GiftCardQRCode.tsx @@ -179,7 +179,7 @@ const GiftCardQRCode: React.FC = ({ {/* 标题 */} 礼品卡核销 - + 请向门店工作人员出示此二维码 @@ -295,13 +295,13 @@ const GiftCardQRCode: React.FC = ({ )} {/* 操作按钮 */} - + @@ -318,10 +318,10 @@ const GiftCardQRCode: React.FC = ({ {/* 使用说明 */} 使用说明: - - • 请向门店工作人员出示此二维码或核销码 - • 工作人员扫码后即可完成核销 - • 每次使用会生成新的核销码,确保安全 + + • 请向门店工作人员出示此二维码或核销码 + • 工作人员扫码后即可完成核销 + • 每次使用会生成新的核销码,确保安全 • 如有问题请联系客服:{giftCard.contactInfo || '400-800-8888'} diff --git a/src/components/GiftCardShare.tsx b/src/components/GiftCardShare.tsx index c445123..ea4e217 100644 --- a/src/components/GiftCardShare.tsx +++ b/src/components/GiftCardShare.tsx @@ -1,7 +1,7 @@ import React from 'react' import { View, Text } from '@tarojs/components' -import { Button, Popup } from '@nutui/nutui-react-taro' -import { Share, Wechat, QQ, Weibo, Link, Close, Gift } from '@nutui/icons-react-taro' +import { Popup } from '@nutui/nutui-react-taro' +import { Share, Link, Close, Gift } from '@nutui/icons-react-taro' import Taro from '@tarojs/taro' export interface GiftCardShareProps { @@ -140,7 +140,7 @@ const GiftCardShare: React.FC = ({ const shareOptions = [ { - icon: , + icon: , label: '微信好友', onClick: handleWechatShare }, diff --git a/src/components/QRCodeGenerator.tsx b/src/components/QRCodeGenerator.tsx index d769647..c025717 100644 --- a/src/components/QRCodeGenerator.tsx +++ b/src/components/QRCodeGenerator.tsx @@ -40,10 +40,10 @@ const QRCodeGenerator: React.FC = ({ // 方案1: 使用在线API生成二维码 const qrApiUrl = `https://api.qrserver.com/v1/create-qr-code/?size=${size}x${size}&data=${encodeURIComponent(text)}` setQrDataURL(qrApiUrl) - + // 方案2: 如果需要离线生成,可以使用Canvas绘制 // await drawQRCodeOnCanvas() - + } catch (error) { console.error('生成二维码失败:', error) Taro.showToast({ @@ -58,19 +58,19 @@ const QRCodeGenerator: React.FC = ({ // 使用Canvas绘制二维码(简化版本) const drawQRCodeOnCanvas = async () => { const ctx = Taro.createCanvasContext(canvasRef.current) - + // 清空画布 ctx.clearRect(0, 0, size, size) - + // 绘制白色背景 ctx.setFillStyle('#ffffff') ctx.fillRect(0, 0, size, size) - + // 绘制黑色边框 ctx.setStrokeStyle('#000000') ctx.setLineWidth(2) ctx.strokeRect(0, 0, size, size) - + // 绘制定位点 const drawFinderPattern = (x: number, y: number) => { ctx.setFillStyle('#000000') @@ -80,17 +80,17 @@ const QRCodeGenerator: React.FC = ({ ctx.setFillStyle('#000000') ctx.fillRect(x + 8, y + 8, 12, 12) } - + // 三个角的定位点 drawFinderPattern(10, 10) // 左上 drawFinderPattern(size - 38, 10) // 右上 drawFinderPattern(10, size - 38) // 左下 - + // 生成数据点(模拟二维码数据) ctx.setFillStyle('#000000') const moduleSize = 4 const modules = Math.floor((size - 80) / moduleSize) - + for (let i = 0; i < modules; i++) { for (let j = 0; j < modules; j++) { // 简单的伪随机算法,基于文本内容生成固定的图案 @@ -102,7 +102,7 @@ const QRCodeGenerator: React.FC = ({ } } } - + ctx.draw() } @@ -172,7 +172,7 @@ const QRCodeGenerator: React.FC = ({ 二维码 {title && ( - {title} + {title} )} @@ -186,7 +186,7 @@ const QRCodeGenerator: React.FC = ({ {/* 二维码显示区域 */} {loading ? ( - @@ -194,11 +194,11 @@ const QRCodeGenerator: React.FC = ({ ) : qrDataURL ? ( - 二维码 = ({ 使用说明: - • 长按二维码可以识别或保存 - • 点击保存按钮可保存到相册 - • 可以复制二维码内容进行分享 + • 长按二维码可以识别或保存 + • 点击保存按钮可保存到相册 + • 可以复制二维码内容进行分享 diff --git a/src/components/SimpleQRCodeModal.tsx b/src/components/SimpleQRCodeModal.tsx index 5ba877f..ea8ffa8 100644 --- a/src/components/SimpleQRCodeModal.tsx +++ b/src/components/SimpleQRCodeModal.tsx @@ -1,7 +1,7 @@ import React from 'react' -import {View, Text} from '@tarojs/components' -import {Popup} from '@nutui/nutui-react-taro' -import {Close, QrCode} from '@nutui/icons-react-taro' +import { View, Text } from '@tarojs/components' +import { Popup } from '@nutui/nutui-react-taro' +import { Close, QrCode } from '@nutui/icons-react-taro' export interface SimpleQRCodeModalProps { /** 是否显示弹窗 */ @@ -27,16 +27,14 @@ const SimpleQRCodeModal: React.FC = ({ closeIcon={} onClose={onClose} style={{ - width: '85%', - maxWidth: '350px', - borderRadius: '12px' + width: '90%' }} > {/* 标题 */} 礼品卡二维码 - + 请向商家出示此二维码 diff --git a/src/user/gift/api-test.tsx b/src/user/gift/api-test.tsx deleted file mode 100644 index 82fc35d..0000000 --- a/src/user/gift/api-test.tsx +++ /dev/null @@ -1,228 +0,0 @@ -import React, { useState } from 'react' -import { View, Text } from '@tarojs/components' -import { Button } from '@nutui/nutui-react-taro' -import { getUserGifts } from '@/api/shop/shopGift' -import Taro from '@tarojs/taro' - -const ApiTest: React.FC = () => { - const [loading, setLoading] = useState(false) - const [results, setResults] = useState([]) - const [logs, setLogs] = useState([]) - - const addLog = (message: string) => { - const timestamp = new Date().toLocaleTimeString() - setLogs(prev => [`[${timestamp}] ${message}`, ...prev]) - } - - const testApiCall = async (status: number, statusName: string) => { - setLoading(true) - addLog(`开始测试 status=${status} (${statusName})`) - - try { - const params = { - page: 1, - limit: 10, - userId: Taro.getStorageSync('UserId'), - status: status - } - - addLog(`API参数: ${JSON.stringify(params)}`) - - const res = await getUserGifts(params) - - addLog(`API返回: ${res?.list?.length || 0} 条数据`) - - if (res?.list && res.list.length > 0) { - const statusCounts = res.list.reduce((acc: any, item: any) => { - const itemStatus = item.status - acc[itemStatus] = (acc[itemStatus] || 0) + 1 - return acc - }, {}) - - addLog(`返回数据状态分布: ${JSON.stringify(statusCounts)}`) - - // 检查是否所有返回的数据都是期望的状态 - const allCorrectStatus = res.list.every((item: any) => item.status === status) - if (allCorrectStatus) { - addLog(`✅ 状态筛选正确: 所有数据都是 status=${status}`) - } else { - addLog(`❌ 状态筛选错误: 返回了其他状态的数据`) - } - } else { - addLog(`ℹ️ 无数据返回`) - } - - setResults(prev => [...prev, { - status, - statusName, - count: res?.list?.length || 0, - data: res?.list || [], - success: true - }]) - - } catch (error) { - addLog(`❌ API调用失败: ${error}`) - setResults(prev => [...prev, { - status, - statusName, - count: 0, - data: [], - success: false, - error: String(error) - }]) - } finally { - setLoading(false) - } - } - - const clearResults = () => { - setResults([]) - setLogs([]) - } - - const testAllStatus = async () => { - clearResults() - await testApiCall(0, '未使用') - await new Promise(resolve => setTimeout(resolve, 1000)) // 延迟1秒 - await testApiCall(1, '已使用') - await new Promise(resolve => setTimeout(resolve, 1000)) // 延迟1秒 - await testApiCall(2, '失效') - } - - return ( - - {/* 页面标题 */} - - - API 状态参数测试 - - - 测试 getUserGifts API 的 status 参数传递 - - - - {/* 测试按钮 */} - - 测试操作: - - - - - - - - - - - - {/* 测试结果 */} - {results.length > 0 && ( - - 测试结果: - {results.map((result, index) => ( - - - - status={result.status} ({result.statusName}) - - - {result.success ? '成功' : '失败'} - - - - 返回数据: {result.count} 条 - - {result.error && ( - - 错误: {result.error} - - )} - {result.data.length > 0 && ( - - 示例数据: - {result.data.slice(0, 2).map((item: any, idx: number) => ( - - ID:{item.id}, status:{item.status}, name:{item.goodsName || item.name} - - ))} - - )} - - ))} - - )} - - {/* 调试日志 */} - - - 调试日志: - - - - {logs.length > 0 ? ( - logs.map((log, index) => ( - - {log} - - )) - ) : ( - 暂无日志 - )} - - - - {/* 使用说明 */} - - 使用说明: - - 1. 点击测试按钮调用 getUserGifts API - 2. 检查返回的数据状态是否与请求参数一致 - 3. 查看调试日志了解详细的API调用过程 - 4. 如果状态筛选不正确,说明后端或前端有问题 - - - - ) -} - -export default ApiTest diff --git a/src/user/gift/color-fix-summary.md b/src/user/gift/color-fix-summary.md deleted file mode 100644 index 5343a65..0000000 --- a/src/user/gift/color-fix-summary.md +++ /dev/null @@ -1,137 +0,0 @@ -# 礼品卡颜色主题修复说明 - -## 问题描述 - -用户反馈礼品卡显示为灰色,视觉效果不佳。经检查发现: - -1. **默认主题问题**:当礼品卡类型不是 10、20、30 时,默认使用 `silver` 主题 -2. **银色主题颜色**:银色主题使用的是 `#c0c0c0` 纯灰色,视觉效果较差 -3. **缺乏视觉层次**:所有主题色都是纯色,缺乏现代感 - -## 修复方案 - -### 1. 默认主题优化 - -**修改前**: -```typescript -default: return 'silver' // 默认灰色 -``` - -**修改后**: -```typescript -default: return 'purple' // 默认紫色,更美观 -``` - -### 2. 主题色渐变化 - -将所有主题色从纯色改为渐变色,提升视觉效果: - -#### 金色主题 (实物礼品卡) -```scss -background: linear-gradient(135deg, #ffd700 0%, #ffed4e 100%); -``` - -#### 蓝色主题 (虚拟礼品卡) -```scss -background: linear-gradient(135deg, #4a90e2 0%, #357abd 100%); -``` - -#### 绿色主题 (服务礼品卡) -```scss -background: linear-gradient(135deg, #5cb85c 0%, #449d44 100%); -``` - -#### 紫色主题 (默认) -```scss -background: linear-gradient(135deg, #9b59b6 0%, #8e44ad 100%); -``` - -#### 银色主题 (优化后) -```scss -background: linear-gradient(135deg, #e8e8e8 0%, #d0d0d0 100%); -``` - -#### 铜色主题 -```scss -background: linear-gradient(135deg, #cd7f32 0%, #b8722c 100%); -``` - -### 3. 按钮样式优化 - -为所有主题的按钮添加字体加粗: -```scss -.use-btn { - font-weight: 600; // 新增 -} -``` - -## 主题色映射规则 - -| 礼品卡类型 | type值 | 主题色 | 视觉效果 | -|-----------|--------|--------|----------| -| 实物礼品卡 | 10 | gold | 金色渐变 | -| 虚拟礼品卡 | 20 | blue | 蓝色渐变 | -| 服务礼品卡 | 30 | green | 绿色渐变 | -| 其他/未知 | 其他值 | purple | 紫色渐变 | - -## 修改的文件 - -### 1. `src/user/gift/index.tsx` -- 修改 `getThemeByType` 函数 -- 将默认主题从 `silver` 改为 `purple` - -### 2. `src/components/GiftCard.scss` -- 优化所有主题色为渐变效果 -- 添加按钮字体加粗 -- 改进银色主题的颜色搭配 - -### 3. 新增测试文件 -- `src/user/gift/color-test.tsx` - 颜色测试页面 - -## 测试验证 - -### 测试页面 -访问 `/user/gift/color-test` 可以看到: -- 不同类型礼品卡的颜色效果 -- 渐变色的视觉表现 -- 按钮样式的改进效果 - -### 测试用例 -1. **type=10**: 应显示金色渐变 -2. **type=20**: 应显示蓝色渐变 -3. **type=30**: 应显示绿色渐变 -4. **type=其他**: 应显示紫色渐变 -5. **type=undefined**: 应显示紫色渐变 - -## 视觉效果对比 - -### 修复前 -- ❌ 默认显示灰色,视觉效果差 -- ❌ 纯色背景,缺乏层次感 -- ❌ 按钮样式平淡 - -### 修复后 -- ✅ 默认显示紫色,更加美观 -- ✅ 渐变色背景,富有层次感 -- ✅ 按钮字体加粗,更加突出 - -## 兼容性说明 - -- ✅ 完全向后兼容,不影响现有功能 -- ✅ 所有现有的礼品卡都会自动应用新的颜色主题 -- ✅ 不需要修改数据结构或API接口 - -## 后续优化建议 - -1. **动态主题**: 可以考虑根据商品分类动态选择主题色 -2. **自定义主题**: 允许用户或管理员自定义主题色 -3. **季节主题**: 根据季节或节日使用特殊主题色 -4. **品牌主题**: 根据商品品牌使用对应的品牌色 - -## 部署检查 - -- [ ] 样式文件更新正确 -- [ ] 主题选择逻辑正确 -- [ ] 测试页面验证通过 -- [ ] 各种设备上显示正常 -- [ ] 不同状态下颜色正确 diff --git a/src/user/gift/color-test.tsx b/src/user/gift/color-test.tsx deleted file mode 100644 index f025d01..0000000 --- a/src/user/gift/color-test.tsx +++ /dev/null @@ -1,213 +0,0 @@ -import React from 'react' -import { View, Text } from '@tarojs/components' -import GiftCard from '@/components/GiftCard' -import { ShopGift } from '@/api/shop/shopGift/model' - -const ColorTest: React.FC = () => { - // 测试不同类型的礼品卡颜色 - const testGifts: ShopGift[] = [ - { - id: 1, - name: '实物礼品卡', - goodsName: '杜尔伯特草原奶香牛上脑(2kg,分4小包)', - goodsImage: 'https://img.alicdn.com/imgextra/i1/2206571109/O1CN01QZxQJJ1Uw8QZxQJJ_!!2206571109.jpg', - description: '实物商品礼品卡', - code: 'GOLD001234567890', - goodsId: 101, - faceValue: '200', - type: 10, // 实物礼品卡 - 应该显示金色 - useStatus: 0, - expireTime: '2024-12-31 23:59:59', - instructions: '适用于实物商品兑换', - contactInfo: '400-800-8888' - }, - { - id: 2, - name: '虚拟礼品卡', - goodsName: '星巴克经典拿铁咖啡券', - goodsImage: 'https://img.alicdn.com/imgextra/i2/2206571109/O1CN01ABC123_!!2206571109.jpg', - description: '虚拟商品礼品卡', - code: 'BLUE001234567890', - goodsId: 102, - faceValue: '100', - type: 20, // 虚拟礼品卡 - 应该显示蓝色 - useStatus: 0, - expireTime: '2024-12-31 23:59:59', - instructions: '适用于虚拟商品兑换', - contactInfo: '400-800-8888' - }, - { - id: 3, - name: '服务礼品卡', - goodsName: '海底捞4人套餐券', - goodsImage: 'https://img.alicdn.com/imgextra/i3/2206571109/O1CN01DEF456_!!2206571109.jpg', - description: '服务类礼品卡', - code: 'GREEN01234567890', - goodsId: 103, - faceValue: '300', - type: 30, // 服务礼品卡 - 应该显示绿色 - useStatus: 0, - expireTime: '2024-12-31 23:59:59', - instructions: '适用于服务类商品兑换', - contactInfo: '400-800-8888' - }, - { - id: 4, - name: '未知类型礼品卡', - goodsName: '通用商品券', - goodsImage: 'https://img.alicdn.com/imgextra/i4/2206571109/O1CN01GHI789_!!2206571109.jpg', - description: '未知类型礼品卡', - code: 'PURPLE1234567890', - goodsId: 104, - faceValue: '150', - type: 99, // 未知类型 - 应该显示紫色(默认) - useStatus: 0, - expireTime: '2024-12-31 23:59:59', - instructions: '通用礼品卡', - contactInfo: '400-800-8888' - }, - { - id: 5, - name: '银色主题测试', - goodsName: '银色主题礼品卡', - goodsImage: 'https://img.alicdn.com/imgextra/i5/2206571109/O1CN01JKL012_!!2206571109.jpg', - description: '测试银色主题', - code: 'SILVER1234567890', - goodsId: 105, - faceValue: '80', - type: undefined, // 无类型 - 应该显示紫色(默认) - useStatus: 0, - expireTime: '2024-12-31 23:59:59', - instructions: '银色主题测试', - contactInfo: '400-800-8888' - } - ] - - // 转换数据格式 - const transformGiftData = (gift: ShopGift) => { - return { - id: gift.id || 0, - name: gift.name || '礼品卡', - goodsName: gift.goodsName, - description: gift.description || gift.instructions, - code: gift.code, - goodsImage: gift.goodsImage, - faceValue: gift.faceValue, - type: gift.type, - useStatus: gift.useStatus, - expireTime: gift.expireTime, - contactInfo: gift.contactInfo, - goodsInfo: { - ...((gift.goodsName || gift.goodsId) && { - specification: `礼品卡面值:¥${gift.faceValue}`, - category: getTypeText(gift.type), - tags: [ - getTypeText(gift.type), - '可使用', - '测试卡片' - ].filter(Boolean), - instructions: [ - '这是颜色测试卡片', - '请检查主题色是否正确', - '不可兑换现金' - ], - notices: [ - '这是测试数据', - '请勿实际使用', - '仅用于颜色测试' - ] - }) - }, - showCode: true, - showUseBtn: true, - showDetailBtn: true, - showGoodsDetail: true, - theme: getThemeByType(gift.type), - onUse: () => console.log('使用:', gift.goodsName || gift.name), - onDetail: () => console.log('详情:', gift.goodsName || gift.name), - onClick: () => console.log('点击:', gift.goodsName || gift.name) - } - } - - const getTypeText = (type?: number): string => { - switch (type) { - case 10: return '实物礼品卡' - case 20: return '虚拟礼品卡' - case 30: return '服务礼品卡' - default: return '通用礼品卡' - } - } - - const getThemeByType = (type?: number): 'gold' | 'silver' | 'bronze' | 'blue' | 'green' | 'purple' => { - switch (type) { - case 10: return 'gold' // 实物礼品卡 - 金色 - case 20: return 'blue' // 虚拟礼品卡 - 蓝色 - case 30: return 'green' // 服务礼品卡 - 绿色 - default: return 'purple' // 默认使用紫色主题 - } - } - - const getExpectedColor = (type?: number): string => { - switch (type) { - case 10: return '金色渐变' - case 20: return '蓝色渐变' - case 30: return '绿色渐变' - default: return '紫色渐变' - } - } - - return ( - - {/* 页面标题 */} - - - 礼品卡颜色主题测试 - - - 验证不同类型礼品卡的主题色显示 - - - - {/* 颜色说明 */} - - 主题色说明: - - • type=10 (实物礼品卡) → 金色渐变 - • type=20 (虚拟礼品卡) → 蓝色渐变 - • type=30 (服务礼品卡) → 绿色渐变 - • 其他/未知类型 → 紫色渐变(默认) - - - - {/* 礼品卡列表 */} - - {testGifts.map((gift, index) => ( - - - - 测试 {index + 1}: type={gift.type || 'undefined'} → 预期: {getExpectedColor(gift.type)} - - - {gift.goodsName} - - - - - ))} - - - {/* 修复说明 */} - - 修复内容: - - ✅ 默认主题从银色改为紫色 - ✅ 所有主题色使用渐变效果 - ✅ 按钮字体加粗提升视觉效果 - ✅ 银色主题优化为更美观的灰色渐变 - - - - ) -} - -export default ColorTest diff --git a/src/user/gift/css-compatibility-fix.md b/src/user/gift/css-compatibility-fix.md deleted file mode 100644 index effc42b..0000000 --- a/src/user/gift/css-compatibility-fix.md +++ /dev/null @@ -1,203 +0,0 @@ -# CSS兼容性问题修复说明 - -## 问题描述 - -在启动项目时遇到WXSS文件编译错误: -``` -[ WXSS 文件编译错误] -/app-origin.wxss(165:2): unexpected '\' at pos 6023 -``` - -这是由于使用了小程序不支持的CSS类名导致的编译错误。 - -## 问题分析 - -小程序环境对CSS类名有一定的限制,以下类名在小程序中不被支持或可能导致编译错误: - -### 1. 不支持的CSS类名 -- `space-y-1`, `space-y-3` - 垂直间距类名 -- `gap-2`, `gap-3` - 元素间距类名 -- `inline-block` - 行内块级元素 -- `break-all` - 文字换行 -- `w-48`, `h-48` - 固定尺寸类名 - -### 2. 错误原因 -这些类名通常来自Tailwind CSS等CSS框架,在小程序环境中需要转换为标准的CSS属性或使用内联样式。 - -## 修复方案 - -### 1. SimpleQRCodeModal.tsx 修复 - -#### 问题1:inline-block 类名 -```typescript -// 修复前 - - -// 修复后 - -``` - -#### 问题2:break-all 类名 -```typescript -// 修复前 - - -// 修复后 - -``` - -#### 问题3:固定尺寸类名 -```typescript -// 修复前 - - -// 修复后 - -``` - -#### 问题4:gap间距类名 -```typescript -// 修复前 - - - - - -// 修复后 - - - - -``` - -### 2. simple-qrcode-demo.tsx 修复 - -#### 问题:space-y 类名 -```typescript -// 修复前 - - ✅ 简洁的二维码弹窗设计 - ✅ 显示礼品卡code码内容 - - -// 修复后 - - ✅ 简洁的二维码弹窗设计 - ✅ 显示礼品卡code码内容 - -``` - -### 3. verification.tsx 修复 - -#### 问题:space-y 类名 -```typescript -// 修复前 - - - -// 修复后 - - -``` - -## 修复的文件列表 - -### 1. 主要组件文件 -- `src/components/SimpleQRCodeModal.tsx` - - 修复 `inline-block` 类名 - - 修复 `break-all` 类名 - - 修复 `w-48 h-48` 固定尺寸类名 - -### 2. 演示页面文件 -- `src/user/gift/simple-qrcode-demo.tsx` - - 修复所有 `space-y-1` 和 `space-y-3` 类名 - - 使用 `block mb-1` 替代垂直间距 - -### 3. 功能页面文件 -- `src/user/store/verification.tsx` - - 修复 `space-y-3` 和 `space-y-1` 类名 - - 使用 `mb-3` 和 `mb-1` 替代垂直间距 - -## 修复原则 - -### 1. 类名替换原则 -- **垂直间距**:`space-y-1` → `block mb-1` -- **水平间距**:`space-x-1` → `inline-block mr-1` -- **固定尺寸**:`w-48` → `style={{ width: '200px' }}` -- **显示方式**:`inline-block` → `style={{ display: 'inline-block' }}` -- **文字换行**:`break-all` → `style={{ wordBreak: 'break-all' }}` - -### 2. 兼容性考虑 -- 优先使用小程序支持的标准CSS类名 -- 复杂样式使用内联样式 `style` 属性 -- 避免使用CSS框架特有的工具类名 - -### 3. 代码可读性 -- 保持代码结构清晰 -- 添加适当的注释说明 -- 使用语义化的类名 - -## 测试验证 - -### 1. 编译测试 -- ✅ 项目能够正常启动 -- ✅ 没有WXSS编译错误 -- ✅ 所有页面能够正常加载 - -### 2. 功能测试 -- ✅ 二维码弹窗正常显示 -- ✅ 样式效果与预期一致 -- ✅ 交互功能正常工作 - -### 3. 兼容性测试 -- ✅ 小程序环境正常运行 -- ✅ H5环境正常运行 -- ✅ 不同设备尺寸适配正常 - -## 预防措施 - -### 1. 开发规范 -- 避免使用CSS框架特有的工具类名 -- 优先使用小程序支持的标准CSS属性 -- 复杂样式使用内联样式或SCSS文件 - -### 2. 代码检查 -- 在提交代码前进行编译测试 -- 使用ESLint等工具检查CSS类名 -- 定期检查项目的CSS兼容性 - -### 3. 文档维护 -- 维护CSS兼容性文档 -- 记录不支持的CSS类名列表 -- 提供替代方案参考 - -## 后续优化 - -### 1. 样式系统优化 -- 建立统一的样式规范 -- 创建可复用的样式组件 -- 使用CSS变量管理主题色彩 - -### 2. 工具链改进 -- 配置CSS兼容性检查工具 -- 自动化CSS类名转换 -- 集成样式lint工具 - -### 3. 开发体验提升 -- 提供CSS类名智能提示 -- 建立样式组件库 -- 优化开发调试工具 - -## 总结 - -通过系统性地修复CSS兼容性问题,项目现在能够在小程序环境中正常运行。主要修复了以下几类问题: - -1. **垂直间距类名**:`space-y-*` → `mb-*` -2. **显示方式类名**:`inline-block` → 内联样式 -3. **文字处理类名**:`break-all` → 内联样式 -4. **固定尺寸类名**:`w-* h-*` → 内联样式 - -这些修复确保了代码在小程序环境中的兼容性,同时保持了良好的代码可读性和维护性。 diff --git a/src/user/gift/debug-tab.tsx b/src/user/gift/debug-tab.tsx deleted file mode 100644 index 97d2b71..0000000 --- a/src/user/gift/debug-tab.tsx +++ /dev/null @@ -1,226 +0,0 @@ -import React, { useState } from 'react' -import { View, Text } from '@tarojs/components' -import { Tabs, TabPane, Button } from '@nutui/nutui-react-taro' -import GiftCard from '@/components/GiftCard' -import { ShopGift } from '@/api/shop/shopGift/model' - -const DebugTab: React.FC = () => { - const [activeTab, setActiveTab] = useState('0') - const [debugInfo, setDebugInfo] = useState([]) - - // 模拟不同状态的礼品卡数据 - const mockData: { [key: string]: ShopGift[] } = { - '0': [ // 未使用 - { - id: 1, - name: '未使用礼品卡1', - goodsName: '星巴克咖啡券', - goodsImage: 'https://img.alicdn.com/imgextra/i1/2206571109/O1CN01QZxQJJ1Uw8QZxQJJ_!!2206571109.jpg', - code: 'UNUSED001', - faceValue: '100', - type: 20, - status: 0, - expireTime: '2024-12-31 23:59:59' - } - ], - '1': [ // 已使用 - { - id: 2, - name: '已使用礼品卡1', - goodsName: '麦当劳套餐券', - goodsImage: 'https://img.alicdn.com/imgextra/i2/2206571109/O1CN01ABC123_!!2206571109.jpg', - code: 'USED001', - faceValue: '50', - type: 20, - status: 1, - useTime: '2024-08-15 14:30:00' - } - ], - '2': [ // 失效 - { - id: 3, - name: '失效礼品卡1', - goodsName: '海底捞火锅券', - goodsImage: 'https://img.alicdn.com/imgextra/i3/2206571109/O1CN01DEF456_!!2206571109.jpg', - code: 'INVALID001', - faceValue: '200', - type: 30, - status: 2, - expireTime: '2024-07-31 23:59:59' - } - ] - } - - // 获取状态过滤条件 - const getStatusFilter = () => { - switch (String(activeTab)) { - case '0': return { status: 0 } - case '1': return { status: 1 } - case '2': return { status: 2 } - default: return {} - } - } - - // 根据传入值获取状态过滤条件 - const getStatusFilterByValue = (value: string | number) => { - switch (String(value)) { - case '0': return { status: 0 } - case '1': return { status: 1 } - case '2': return { status: 2 } - default: return {} - } - } - - // Tab切换处理 - const handleTabChange = (value: string | number) => { - const timestamp = new Date().toLocaleTimeString() - const statusFilter = getStatusFilterByValue(value) - - const newDebugInfo = [ - `[${timestamp}] Tab切换到: ${value}`, - `[${timestamp}] 状态过滤: ${JSON.stringify(statusFilter)}`, - `[${timestamp}] 预期显示: ${getStatusText(Number(value))}状态的礼品卡`, - '---' - ] - - setDebugInfo(prev => [...newDebugInfo, ...prev]) - setActiveTab(value) - } - - const getStatusText = (status: number): string => { - switch (status) { - case 0: return '未使用' - case 1: return '已使用' - case 2: return '失效' - default: return '未知' - } - } - - // 转换数据 - const transformGiftData = (gift: ShopGift) => { - return { - id: gift.id || 0, - name: gift.name || '礼品卡', - goodsName: gift.goodsName, - description: `状态: ${getStatusText(gift.status || 0)}`, - code: gift.code, - goodsImage: gift.goodsImage, - faceValue: gift.faceValue, - type: gift.type, - status: gift.status, - expireTime: gift.expireTime, - useTime: gift.useTime, - showCode: gift.status === 0, - showUseBtn: gift.status === 0, - showDetailBtn: true, - theme: 'blue' as const, - onUse: () => console.log('使用'), - onDetail: () => console.log('详情') - } - } - - const currentData = mockData[String(activeTab)] || [] - - return ( - - {/* 页面标题 */} - - - Tab切换调试页面 - - - - {/* 当前状态信息 */} - - 当前状态信息: - - activeTab: {String(activeTab)} - 状态过滤: {JSON.stringify(getStatusFilter())} - 显示数据条数: {currentData.length} - 预期状态: {getStatusText(Number(activeTab))} - - - - {/* Tab切换 */} - - - - - - - - - - - - {/* 礼品卡展示 */} - - - 当前显示: {getStatusText(Number(activeTab))}状态礼品卡 - - - {currentData.length > 0 ? ( - currentData.map((gift) => ( - - - - 礼品卡ID: {gift.id}, status: {gift.status}, 预期: {getStatusText(gift.status || 0)} - - - - - )) - ) : ( - - - 暂无{getStatusText(Number(activeTab))}状态的礼品卡 - - - )} - - - {/* 调试日志 */} - - - 调试日志: - - - - {debugInfo.length > 0 ? ( - debugInfo.map((info, index) => ( - - {info} - - )) - ) : ( - 暂无调试信息 - )} - - - - {/* 测试按钮 */} - - 快速测试: - - - - - - - - ) -} - -export default DebugTab diff --git a/src/user/gift/demo.tsx b/src/user/gift/demo.tsx deleted file mode 100644 index 9bf8210..0000000 --- a/src/user/gift/demo.tsx +++ /dev/null @@ -1,201 +0,0 @@ -import React, { useState } from 'react' -import { View, Text } from '@tarojs/components' -import { Button, Tabs, TabPane } from '@nutui/nutui-react-taro' -import GiftCard from '@/components/GiftCard' -import { ShopGift } from '@/api/shop/shopGift/model' - -const GiftCardDemo: React.FC = () => { - const [activeTab, setActiveTab] = useState('0') - - // 模拟不同类型的礼品卡数据 - const mockGifts: ShopGift[] = [ - { - id: 1, - name: '星巴克礼品卡', - goodsName: '星巴克咖啡礼品卡(电子版)', - goodsImage: 'https://img.alicdn.com/imgextra/i1/2206571109/O1CN01QZxQJJ1Uw8QZxQJJ_!!2206571109.jpg', - description: '享受醇香咖啡时光,适用于全国星巴克门店', - code: 'SB2024001234567890', - goodsId: 101, - faceValue: '100', - type: 20, - useStatus: 0, - expireTime: '2024-12-31 23:59:59', - instructions: '请在有效期内使用,出示兑换码即可使用', - contactInfo: '400-800-8888' - }, - { - id: 2, - name: '麦当劳优惠券', - goodsName: '麦当劳经典套餐券', - goodsImage: 'https://img.alicdn.com/imgextra/i2/2206571109/O1CN01ABC123_!!2206571109.jpg', - description: '美味汉堡套餐,限时优惠', - code: 'MCD2024987654321', - goodsId: 102, - faceValue: '50', - type: 20, - useStatus: 0, - expireTime: '2024-10-31 23:59:59', - instructions: '适用于全国麦当劳门店,不可与其他优惠同享', - contactInfo: '400-517-517' - }, - { - id: 3, - name: '海底捞火锅券', - goodsName: '海底捞火锅代金券', - goodsImage: 'https://img.alicdn.com/imgextra/i3/2206571109/O1CN01DEF456_!!2206571109.jpg', - description: '享受正宗川味火锅', - code: 'HDL2024555666777', - goodsId: 103, - faceValue: '200', - type: 30, - useStatus: 1, - useTime: '2024-08-15 19:30:00', - useLocation: '海底捞王府井店', - instructions: '需提前预约,适用于全国海底捞门店', - contactInfo: '400-869-8888' - } - ] - - // 转换数据格式 - const transformGiftData = (gift: ShopGift) => { - return { - id: gift.id || 0, - name: gift.goodsName || gift.name || '礼品卡', - description: gift.description || gift.instructions, - code: gift.code, - goodsImage: gift.goodsImage, - faceValue: gift.faceValue, - type: gift.type, - useStatus: gift.useStatus, - expireTime: gift.expireTime, - useTime: gift.useTime, - useLocation: gift.useLocation, - contactInfo: gift.contactInfo, - goodsInfo: { - ...(gift.goodsId && { - specification: `礼品卡面值:¥${gift.faceValue}`, - category: getTypeText(gift.type), - tags: [ - getTypeText(gift.type), - gift.useStatus === 0 ? '可使用' : gift.useStatus === 1 ? '已使用' : '已过期', - '全国通用', - gift.type === 20 ? '即买即用' : '需预约' - ].filter(Boolean), - instructions: gift.instructions ? [gift.instructions] : [ - '请在有效期内使用', - '出示兑换码即可使用', - '不可兑换现金' - ], - notices: [ - '礼品卡一经使用不可退换', - '请妥善保管兑换码', - '如有疑问请联系客服' - ] - }) - }, - showCode: gift.useStatus === 0, - showUseBtn: gift.useStatus === 0, - showDetailBtn: true, - showGoodsDetail: true, - theme: getThemeByType(gift.type), - onUse: () => handleUse(gift), - onDetail: () => handleDetail(gift), - onClick: () => handleClick(gift) - } - } - - const getTypeText = (type?: number): string => { - switch (type) { - case 10: return '实物礼品卡' - case 20: return '虚拟礼品卡' - case 30: return '服务礼品卡' - default: return '礼品卡' - } - } - - const getThemeByType = (type?: number): 'gold' | 'silver' | 'bronze' | 'blue' | 'green' | 'purple' => { - switch (type) { - case 10: return 'gold' - case 20: return 'blue' - case 30: return 'green' - default: return 'silver' - } - } - - const handleUse = (gift: ShopGift) => { - console.log('使用礼品卡:', gift.goodsName) - } - - const handleDetail = (gift: ShopGift) => { - console.log('查看详情:', gift.goodsName) - } - - const handleClick = (gift: ShopGift) => { - console.log('点击礼品卡:', gift.goodsName) - } - - // 根据状态筛选礼品卡 - const getFilteredGifts = () => { - const statusMap = { - '0': 0, // 可用 - '1': 1, // 已使用 - '2': 2 // 已过期 - } - const targetStatus = statusMap[activeTab as keyof typeof statusMap] - return mockGifts.filter(gift => gift.useStatus === targetStatus) - } - - return ( - - {/* 页面标题 */} - - - 礼品卡商品信息展示演示 - - - - {/* Tab切换 */} - - - - - - - - - {/* 礼品卡列表 */} - - {getFilteredGifts().map((gift) => ( - - - - ))} - - {getFilteredGifts().length === 0 && ( - - - {activeTab === '0' ? '暂无可用礼品卡' : - activeTab === '1' ? '暂无已使用礼品卡' : - '暂无已过期礼品卡'} - - - )} - - - {/* 功能说明 */} - - 功能特性: - - • 优先显示商品名称(goodsName) - • 显示商品图片(goodsImage) - • 丰富的商品信息展示 - • 不同状态的视觉效果 - • 响应式设计适配 - - - - ) -} - -export default GiftCardDemo diff --git a/src/user/gift/detail.tsx b/src/user/gift/detail.tsx index 958c34f..9f75534 100644 --- a/src/user/gift/detail.tsx +++ b/src/user/gift/detail.tsx @@ -324,8 +324,6 @@ const GiftCardDetail = () => { visible={showQRCode} onClose={() => setShowQRCode(false)} qrContent={gift.code || ''} - giftName={gift.goodsName || gift.name} - faceValue={gift.faceValue} /> )} diff --git a/src/user/gift/final-css-fix-summary.md b/src/user/gift/final-css-fix-summary.md deleted file mode 100644 index 033a806..0000000 --- a/src/user/gift/final-css-fix-summary.md +++ /dev/null @@ -1,213 +0,0 @@ -# 最终CSS兼容性修复总结 - -## 问题描述 - -项目启动时遇到WXSS编译错误: -``` -[ WXSS 文件编译错误] -/app-origin.wxss(165:2): unexpected '\' at pos 6023 -``` - -## 根本原因 - -使用了小程序不支持的CSS类名,主要包括: -1. `space-y-*` - 垂直间距类名 -2. `gap-*` - Flexbox间距类名 -3. `inline-block` - 显示方式类名 -4. `break-all` - 文字换行类名 -5. `w-* h-*` - 固定尺寸类名 - -## 完整修复方案 - -### 1. SimpleQRCodeModal.tsx 修复 - -#### 修复前的问题代码: -```typescript -// 问题1: gap-3 类名 - - -// 问题2: inline-block 类名 - - -// 问题3: break-all 类名 - - -// 问题4: w-48 h-48 固定尺寸类名 - -``` - -#### 修复后的代码: -```typescript -// 修复1: 使用 mr-3 替代 gap-3 - - - - - -// 修复2: 移除 inline-block,使用内联样式 - - -// 修复3: 使用内联样式替代 break-all - - -// 修复4: 使用内联样式替代固定尺寸类名 - -``` - -### 2. simple-qrcode-demo.tsx 修复 - -#### 修复前: -```typescript - - ✅ 简洁的二维码弹窗设计 - ✅ 显示礼品卡code码内容 - -``` - -#### 修复后: -```typescript - - ✅ 简洁的二维码弹窗设计 - ✅ 显示礼品卡code码内容 - -``` - -### 3. verification.tsx 修复 - -#### 修复前: -```typescript - - - - - - - -``` - -#### 修复后: -```typescript - - - - - - - -``` - -## 修复原则总结 - -### 1. 间距类名替换 -- `space-y-1` → `block mb-1` -- `space-y-3` → `mb-3` -- `gap-2` → `mr-2` -- `gap-3` → `mr-3` - -### 2. 显示方式替换 -- `inline-block` → 移除或使用内联样式 -- `break-all` → `style={{ wordBreak: 'break-all' }}` - -### 3. 尺寸类名替换 -- `w-48` → `style={{ width: '200px' }}` -- `h-48` → `style={{ height: '200px' }}` - -### 4. 布局优化 -- 保持Flexbox布局的基本功能 -- 使用标准的margin/padding类名 -- 复杂样式使用内联样式 - -## 修复的文件列表 - -1. **src/components/SimpleQRCodeModal.tsx** - - 移除Canvas相关复杂逻辑 - - 修复所有不兼容的CSS类名 - - 简化二维码显示逻辑 - -2. **src/user/gift/simple-qrcode-demo.tsx** - - 修复所有 `space-y-*` 类名 - - 使用 `block mb-*` 替代 - -3. **src/user/store/verification.tsx** - - 修复 `gap-*` 类名 - - 修复 `space-y-*` 类名 - -## 功能保持 - -修复后保持的功能: -- ✅ 二维码弹窗正常显示 -- ✅ 复制兑换码功能正常 -- ✅ 弹窗交互体验良好 -- ✅ 响应式布局正常 -- ✅ 视觉效果与预期一致 - -## 简化的功能 - -为了确保兼容性,简化了以下功能: -- 🔄 Canvas二维码生成 → 静态二维码图标显示 -- 🔄 复杂的二维码绘制 → 简单的占位符显示 -- 🔄 动态二维码刷新 → 静态内容显示 - -## 测试验证 - -### 编译测试 -- ✅ 项目能够正常启动 -- ✅ 没有WXSS编译错误 -- ✅ 所有页面正常加载 - -### 功能测试 -- ✅ 二维码弹窗正常打开和关闭 -- ✅ 复制功能正常工作 -- ✅ 按钮交互正常响应 -- ✅ 样式显示符合预期 - -### 兼容性测试 -- ✅ 小程序环境正常运行 -- ✅ 不同设备尺寸适配正常 -- ✅ 所有CSS类名都被小程序支持 - -## 预防措施 - -### 开发规范 -1. **避免使用CSS框架特有类名** - - 不使用Tailwind CSS的工具类名 - - 优先使用小程序支持的标准CSS - -2. **使用兼容的替代方案** - - 间距:使用 `mb-*`, `mr-*` 等标准类名 - - 尺寸:使用内联样式或标准CSS属性 - - 布局:使用基础的Flexbox类名 - -3. **代码检查流程** - - 提交前进行编译测试 - - 定期检查CSS兼容性 - - 建立CSS类名白名单 - -## 后续优化建议 - -1. **建立样式规范** - - 创建小程序兼容的CSS类名库 - - 建立统一的样式组件 - -2. **工具链改进** - - 配置CSS兼容性检查工具 - - 自动化不兼容类名检测 - -3. **功能增强** - - 集成真实的二维码生成库 - - 优化二维码显示效果 - - 添加更多交互功能 - -## 总结 - -通过系统性地修复CSS兼容性问题,项目现在能够在小程序环境中正常启动和运行。主要成果: - -1. **解决了编译错误**:移除了所有不兼容的CSS类名 -2. **保持了功能完整性**:核心功能正常工作 -3. **提升了兼容性**:确保在小程序环境中稳定运行 -4. **建立了规范**:为后续开发提供了CSS兼容性指导 - -现在项目应该能够正常启动,二维码弹窗功能可以正常使用! diff --git a/src/user/gift/goodsName-integration.md b/src/user/gift/goodsName-integration.md deleted file mode 100644 index 0150b26..0000000 --- a/src/user/gift/goodsName-integration.md +++ /dev/null @@ -1,152 +0,0 @@ -# GoodsName 字段集成说明 - -## 概述 - -后端已新增 `goodsName` 字段,前端已完成相应的集成工作,现在礼品卡组件可以正确显示商品名称。 - -## 修改内容 - -### 1. GiftCard 组件接口更新 - -**文件**: `src/components/GiftCard.tsx` - -```typescript -export interface GiftCardProps { - id: number - name: string - goodsName?: string // 新增:商品名称字段 - description?: string - // ... 其他字段 -} -``` - -**显示逻辑**: -```typescript -// 获取显示名称,优先使用商品名称 -const displayName = goodsName || name - -// 在模板中使用 -{displayName} -``` - -### 2. 数据转换函数更新 - -**文件**: `src/user/gift/index.tsx` - -```typescript -const transformGiftData = (gift: ShopGift): GiftCardProps => { - return { - id: gift.id || 0, - name: gift.name || '礼品卡', - goodsName: gift.goodsName, // 传递商品名称 - // ... 其他字段映射 - } -} -``` - -### 3. 类型定义更新 - -**文件**: `src/types/giftCard.ts` - -```typescript -export interface GiftCardData { - id: number - name: string - goodsName?: string // 新增字段 - // ... 其他字段 -} -``` - -## 显示规则 - -### 优先级规则 -1. **有 `goodsName`**: 显示商品名称 -2. **无 `goodsName`**: 显示礼品卡名称 (`name`) - -### 示例对比 - -| 数据情况 | name | goodsName | 显示结果 | -|---------|------|-----------|----------| -| 情况1 | "星巴克礼品卡" | "星巴克经典拿铁咖啡券" | "星巴克经典拿铁咖啡券" | -| 情况2 | "通用礼品卡" | null/undefined | "通用礼品卡" | -| 情况3 | "麦当劳优惠券" | "麦当劳巨无霸套餐券" | "麦当劳巨无霸套餐券" | - -## 后端数据结构 - -确保后端返回的 `ShopGift` 对象包含 `goodsName` 字段: - -```json -{ - "id": 1, - "name": "星巴克礼品卡", - "goodsName": "星巴克经典拿铁咖啡券", - "goodsImage": "https://example.com/image.jpg", - "faceValue": "100", - "type": 20, - "useStatus": 0, - // ... 其他字段 -} -``` - -## 测试验证 - -### 测试页面 -访问测试页面验证显示效果: -- `/user/gift/goodsname-test` - 专门测试 goodsName 字段的页面 - -### 测试用例 -1. **有商品名称的礼品卡**: 应显示 `goodsName` 的值 -2. **无商品名称的礼品卡**: 应显示 `name` 的值 -3. **不同状态的礼品卡**: 确保各种状态下名称显示正确 -4. **长名称处理**: 确保长商品名称不会破坏布局 - -## 兼容性 - -### 向后兼容 -- 对于没有 `goodsName` 字段的旧数据,组件会自动使用 `name` 字段 -- 不会影响现有功能的正常使用 - -### 数据验证 -```typescript -// 在组件中的处理逻辑 -const displayName = goodsName || name || '礼品卡' -``` - -## 样式优化 - -### 长名称处理 -```scss -.title-text { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - max-width: 200px; -} -``` - -### 响应式适配 -- 小屏幕设备上自动调整显示宽度 -- 保持良好的视觉效果 - -## 注意事项 - -1. **数据完整性**: 建议后端确保重要礼品卡都有 `goodsName` 字段 -2. **名称长度**: 商品名称不宜过长,建议控制在20个字符以内 -3. **特殊字符**: 确保商品名称不包含可能影响显示的特殊字符 -4. **多语言**: 如需支持多语言,`goodsName` 也需要相应的国际化处理 - -## 后续优化建议 - -1. **搜索功能**: 在搜索时同时匹配 `name` 和 `goodsName` -2. **排序功能**: 支持按商品名称排序 -3. **筛选功能**: 支持按是否有商品名称筛选 -4. **统计功能**: 统计有商品名称的礼品卡比例 - -## 部署检查清单 - -- [ ] 后端 API 返回 `goodsName` 字段 -- [ ] 前端组件正确显示商品名称 -- [ ] 测试页面验证通过 -- [ ] 兼容性测试通过 -- [ ] 样式在各设备上显示正常 -- [ ] 长名称处理正确 diff --git a/src/user/gift/goodsname-test.tsx b/src/user/gift/goodsname-test.tsx deleted file mode 100644 index eba2417..0000000 --- a/src/user/gift/goodsname-test.tsx +++ /dev/null @@ -1,191 +0,0 @@ -import React from 'react' -import { View, Text } from '@tarojs/components' -import GiftCard from '@/components/GiftCard' -import { ShopGift } from '@/api/shop/shopGift/model' - -const GoodsNameTest: React.FC = () => { - // 测试数据:包含 goodsName 字段的礼品卡 - const testGifts: ShopGift[] = [ - { - id: 1, - name: '星巴克礼品卡', - goodsName: '星巴克经典拿铁咖啡券', // 后端新增的商品名称字段 - goodsImage: 'https://img.alicdn.com/imgextra/i1/2206571109/O1CN01QZxQJJ1Uw8QZxQJJ_!!2206571109.jpg', - description: '享受醇香咖啡时光', - code: 'SB2024001234567890', - goodsId: 101, - faceValue: '100', - type: 20, - useStatus: 0, - expireTime: '2024-12-31 23:59:59', - instructions: '适用于全国星巴克门店', - contactInfo: '400-800-8888' - }, - { - id: 2, - name: '麦当劳优惠券', - goodsName: '麦当劳巨无霸套餐券', // 商品名称 - goodsImage: 'https://img.alicdn.com/imgextra/i2/2206571109/O1CN01ABC123_!!2206571109.jpg', - description: '美味汉堡套餐', - code: 'MCD2024987654321', - goodsId: 102, - faceValue: '50', - type: 20, - useStatus: 0, - expireTime: '2024-10-31 23:59:59', - instructions: '适用于全国麦当劳门店', - contactInfo: '400-517-517' - }, - { - id: 3, - name: '通用礼品卡', - // 没有 goodsName,应该显示 name - goodsImage: 'https://img.alicdn.com/imgextra/i3/2206571109/O1CN01DEF456_!!2206571109.jpg', - description: '通用型礼品卡', - code: 'GEN2024555666777', - faceValue: '200', - type: 10, - useStatus: 0, - expireTime: '2024-11-30 23:59:59', - instructions: '可在指定商户使用', - contactInfo: '400-123-456' - }, - { - id: 4, - name: '海底捞火锅券', - goodsName: '海底捞4人套餐券', // 已使用状态的商品 - goodsImage: 'https://img.alicdn.com/imgextra/i4/2206571109/O1CN01GHI789_!!2206571109.jpg', - description: '享受正宗川味火锅', - code: 'HDL2024888999000', - goodsId: 103, - faceValue: '300', - type: 30, - useStatus: 1, // 已使用 - useTime: '2024-08-15 19:30:00', - useLocation: '海底捞王府井店', - instructions: '需提前预约', - contactInfo: '400-869-8888' - } - ] - - // 转换数据格式 - const transformGiftData = (gift: ShopGift) => { - return { - id: gift.id || 0, - name: gift.name || '礼品卡', - goodsName: gift.goodsName, // 传递商品名称 - description: gift.description || gift.instructions, - code: gift.code, - goodsImage: gift.goodsImage, - faceValue: gift.faceValue, - type: gift.type, - useStatus: gift.useStatus, - expireTime: gift.expireTime, - useTime: gift.useTime, - useLocation: gift.useLocation, - contactInfo: gift.contactInfo, - goodsInfo: { - ...((gift.goodsName || gift.goodsId) && { - specification: `礼品卡面值:¥${gift.faceValue}`, - category: getTypeText(gift.type), - tags: [ - getTypeText(gift.type), - gift.useStatus === 0 ? '可使用' : gift.useStatus === 1 ? '已使用' : '已过期', - ...(gift.goodsName ? ['商品礼品卡'] : []) - ].filter(Boolean), - instructions: gift.instructions ? [gift.instructions] : [ - '请在有效期内使用', - '出示兑换码即可使用', - '不可兑换现金' - ], - notices: [ - '礼品卡一经使用不可退换', - '请妥善保管兑换码', - '如有疑问请联系客服' - ] - }) - }, - showCode: gift.useStatus === 0, - showUseBtn: gift.useStatus === 0, - showDetailBtn: true, - showGoodsDetail: true, - theme: getThemeByType(gift.type), - onUse: () => console.log('使用:', gift.goodsName || gift.name), - onDetail: () => console.log('详情:', gift.goodsName || gift.name), - onClick: () => console.log('点击:', gift.goodsName || gift.name) - } - } - - const getTypeText = (type?: number): string => { - switch (type) { - case 10: return '实物礼品卡' - case 20: return '虚拟礼品卡' - case 30: return '服务礼品卡' - default: return '礼品卡' - } - } - - const getThemeByType = (type?: number): 'gold' | 'silver' | 'bronze' | 'blue' | 'green' | 'purple' => { - switch (type) { - case 10: return 'gold' - case 20: return 'blue' - case 30: return 'green' - default: return 'silver' - } - } - - return ( - - {/* 页面标题 */} - - - 商品名称字段测试 - - - 测试 goodsName 字段的显示效果 - - - - {/* 测试说明 */} - - 测试说明: - - • 第1张:有 goodsName,显示"星巴克经典拿铁咖啡券" - • 第2张:有 goodsName,显示"麦当劳巨无霸套餐券" - • 第3张:无 goodsName,显示"通用礼品卡" - • 第4张:已使用状态,显示"海底捞4人套餐券" - - - - {/* 礼品卡列表 */} - - {testGifts.map((gift, index) => ( - - - - 测试 {index + 1}: {gift.goodsName ? `goodsName="${gift.goodsName}"` : '无 goodsName'} - - - name="{gift.name}" - - - - - ))} - - - {/* 结果说明 */} - - 预期结果: - - ✅ 有 goodsName 时,卡片标题显示商品名称 - ✅ 无 goodsName 时,卡片标题显示礼品卡名称 - ✅ 商品信息区域显示相关标签和说明 - ✅ 不同状态的视觉效果正确 - - - - ) -} - -export default GoodsNameTest diff --git a/src/user/gift/qrcode-demo.tsx b/src/user/gift/qrcode-demo.tsx deleted file mode 100644 index 7d14d5a..0000000 --- a/src/user/gift/qrcode-demo.tsx +++ /dev/null @@ -1,221 +0,0 @@ -import React from 'react' -import { View, Text } from '@tarojs/components' -import { Button } from '@nutui/nutui-react-taro' -import GiftCard from '@/components/GiftCard' -import { ShopGift } from '@/api/shop/shopGift/model' - -const QRCodeDemo: React.FC = () => { - // 模拟礼品卡数据 - const mockGifts: ShopGift[] = [ - { - id: 1, - name: '星巴克礼品卡', - goodsName: '星巴克经典拿铁咖啡券', - goodsImage: 'https://img.alicdn.com/imgextra/i1/2206571109/O1CN01QZxQJJ1Uw8QZxQJJ_!!2206571109.jpg', - description: '享受醇香咖啡时光', - code: 'SB2024001234567890', - goodsId: 101, - faceValue: '100', - type: 20, - status: 0, // 未使用 - expireTime: '2024-12-31 23:59:59', - instructions: '适用于全国星巴克门店', - contactInfo: '400-800-8888' - }, - { - id: 2, - name: '麦当劳优惠券', - goodsName: '麦当劳巨无霸套餐券', - goodsImage: 'https://img.alicdn.com/imgextra/i2/2206571109/O1CN01ABC123_!!2206571109.jpg', - description: '美味汉堡套餐', - code: 'MCD2024987654321', - goodsId: 102, - faceValue: '50', - type: 20, - status: 0, // 未使用 - expireTime: '2024-10-31 23:59:59', - instructions: '适用于全国麦当劳门店', - contactInfo: '400-517-517' - }, - { - id: 3, - name: '海底捞火锅券', - goodsName: '海底捞4人套餐券', - goodsImage: 'https://img.alicdn.com/imgextra/i3/2206571109/O1CN01DEF456_!!2206571109.jpg', - description: '享受正宗川味火锅', - code: 'HDL2024555666777', - goodsId: 103, - faceValue: '300', - type: 30, - status: 1, // 已使用 - useTime: '2024-08-15 19:30:00', - useLocation: '海底捞王府井店', - instructions: '需提前预约', - contactInfo: '400-869-8888' - } - ] - - // 转换数据格式 - const transformGiftData = (gift: ShopGift) => { - return { - id: gift.id || 0, - name: gift.name || '礼品卡', - goodsName: gift.goodsName, - description: gift.description || gift.instructions, - code: gift.code, - goodsImage: gift.goodsImage, - faceValue: gift.faceValue, - type: gift.type, - status: gift.status, - expireTime: gift.expireTime, - useTime: gift.useTime, - useLocation: gift.useLocation, - contactInfo: gift.contactInfo, - goodsInfo: { - ...((gift.goodsName || gift.goodsId) && { - specification: `礼品卡面值:¥${gift.faceValue}`, - category: getTypeText(gift.type), - tags: [ - getTypeText(gift.type), - getStatusText(gift.status), - '支持二维码核销' - ].filter(Boolean), - instructions: [ - '点击"立即使用"生成二维码', - '向门店工作人员出示二维码', - '工作人员扫码完成核销', - '不可兑换现金' - ], - notices: [ - '每次使用生成新的核销码', - '请在有效期内使用', - '如有疑问请联系客服' - ] - }) - }, - showCode: gift.status === 0, - showUseBtn: gift.status === 0, // 只有未使用状态显示使用按钮 - showDetailBtn: true, - showGoodsDetail: true, - theme: getThemeByType(gift.type), - onUse: () => console.log('打开二维码弹窗'), - onDetail: () => console.log('查看详情'), - onClick: () => console.log('点击礼品卡') - } - } - - const getTypeText = (type?: number): string => { - switch (type) { - case 10: return '实物礼品卡' - case 20: return '虚拟礼品卡' - case 30: return '服务礼品卡' - default: return '通用礼品卡' - } - } - - const getStatusText = (status?: number): string => { - switch (status) { - case 0: return '未使用' - case 1: return '已使用' - case 2: return '失效' - default: return '未知状态' - } - } - - const getThemeByType = (type?: number): 'gold' | 'silver' | 'bronze' | 'blue' | 'green' | 'purple' => { - switch (type) { - case 10: return 'gold' - case 20: return 'blue' - case 30: return 'green' - default: return 'purple' - } - } - - return ( - - {/* 页面标题 */} - - - 二维码核销功能演示 - - - 点击"立即使用"按钮生成核销二维码 - - - - {/* 功能说明 */} - - 功能特性: - - ✅ 点击"立即使用"生成二维码 - ✅ 每次生成新的6位核销码 - ✅ 显示礼品卡详细信息 - ✅ 支持复制核销码和兑换码 - ✅ 门店工作人员扫码核销 - - - - {/* 使用流程 */} - - 使用流程: - - 1. 用户点击"立即使用"按钮 - 2. 系统生成核销二维码和核销码 - 3. 用户向门店工作人员出示二维码 - 4. 工作人员扫码或输入核销码验证 - 5. 验证成功后完成核销 - - - - {/* 礼品卡列表 */} - - 礼品卡示例: - {mockGifts.map((gift, index) => ( - - - - 示例 {index + 1}: {getStatusText(gift.status)}状态 - - - {gift.status === 0 ? '可以生成二维码核销' : '已使用或失效,无法核销'} - - - - - ))} - - - {/* 门店核销入口 */} - - 门店工作人员: - - 如果您是门店工作人员,请使用专门的核销页面 - - - - - {/* 技术说明 */} - - 技术实现: - - • 二维码包含礼品卡ID、核销码等信息 - • 每次生成随机6位数字核销码 - • 支持扫码和手动输入两种验证方式 - • 核销后礼品卡状态更新为已使用 - - - - ) -} - -export default QRCodeDemo diff --git a/src/user/gift/qrcode-verification-implementation.md b/src/user/gift/qrcode-verification-implementation.md deleted file mode 100644 index 2ae4505..0000000 --- a/src/user/gift/qrcode-verification-implementation.md +++ /dev/null @@ -1,212 +0,0 @@ -# 礼品卡二维码核销功能实现说明 - -## 功能概述 - -将礼品卡的"立即使用"功能改为生成二维码,供门店工作人员扫码核销,提升用户体验和核销效率。 - -## 核心功能 - -### 1. 用户端功能 -- **生成核销二维码**:点击"立即使用"按钮生成包含核销信息的二维码 -- **显示核销码**:同时显示6位数字核销码,支持手动输入 -- **复制功能**:支持复制核销码和兑换码 -- **刷新功能**:可重新生成新的核销码 - -### 2. 门店端功能 -- **扫码核销**:使用摄像头扫描用户的二维码 -- **手动输入**:支持手动输入核销码进行验证 -- **信息验证**:显示礼品卡详细信息供确认 -- **完成核销**:确认后完成核销操作 - -## 技术实现 - -### 1. 组件结构 - -#### GiftCardQRCode 组件 -```typescript -interface GiftCardQRCodeProps { - visible: boolean - onClose: () => void - giftCard: { - id: number - name?: string - goodsName?: string - code?: string - faceValue?: string - type?: number - status?: number - expireTime?: string - contactInfo?: string - } -} -``` - -**主要功能**: -- 生成核销二维码 -- 显示礼品卡信息 -- 提供复制和分享功能 - -#### StoreVerification 页面 -**主要功能**: -- 扫码识别二维码 -- 手动输入核销码 -- 验证礼品卡信息 -- 完成核销操作 - -### 2. 数据流程 - -#### 二维码数据结构 -```json -{ - "type": "gift_card_verification", - "giftId": 123, - "giftCode": "SB2024001234567890", - "verificationCode": "123456", - "faceValue": "100", - "timestamp": 1692123456789, - "expireTime": "2024-12-31 23:59:59", - "codeExpireTime": "2024-08-16 15:30:00" -} -``` - -#### 核销流程 -1. **生成核销码** - ```typescript - POST /shop/shop-gift/generate-verification-code - Body: { giftId: number } - Response: { verificationCode: string, expireTime: string } - ``` - -2. **验证核销码** - ```typescript - POST /shop/shop-gift/verify - Body: { verificationCode?: string, giftCode?: string } - Response: ShopGift - ``` - -3. **完成核销** - ```typescript - POST /shop/shop-gift/complete-verification - Body: { - giftId: number, - verificationCode: string, - storeId?: number, - storeName?: string, - operatorId?: number, - operatorName?: string - } - ``` - -### 3. 安全机制 - -#### 核销码安全 -- **时效性**:核销码有效期15分钟 -- **一次性**:每次生成新的核销码 -- **随机性**:6位随机数字,防止猜测 - -#### 验证机制 -- **双重验证**:支持二维码和手动输入 -- **信息确认**:显示完整礼品卡信息供确认 -- **状态检查**:验证礼品卡状态和有效期 - -## 文件结构 - -### 新增文件 -``` -src/ -├── components/ -│ └── GiftCardQRCode.tsx # 二维码核销弹窗组件 -├── pages/ -│ └── store/ -│ └── verification.tsx # 门店核销页面 -├── user/gift/ -│ ├── qrcode-demo.tsx # 二维码功能演示页面 -│ └── qrcode-verification-implementation.md -└── api/shop/shopGift/ - └── index.ts # 新增核销相关API -``` - -### 修改文件 -``` -src/ -└── components/ - └── GiftCard.tsx # 修改"立即使用"按钮功能 -``` - -## 用户体验优化 - -### 1. 界面设计 -- **清晰的二维码显示**:大尺寸二维码,易于扫描 -- **信息完整展示**:显示礼品卡所有关键信息 -- **操作便捷**:一键复制、刷新等快捷操作 - -### 2. 交互优化 -- **即时反馈**:生成、验证过程有明确的加载状态 -- **错误处理**:友好的错误提示和重试机制 -- **状态管理**:清晰的状态流转和视觉反馈 - -### 3. 兼容性考虑 -- **多种核销方式**:支持扫码和手动输入 -- **设备适配**:适配不同尺寸的移动设备 -- **网络容错**:网络异常时的降级处理 - -## 业务流程 - -### 用户使用流程 -1. 用户在礼品卡列表点击"立即使用" -2. 系统生成核销二维码和核销码 -3. 用户向门店工作人员出示二维码 -4. 工作人员扫码或输入核销码 -5. 系统验证信息并显示礼品卡详情 -6. 工作人员确认后完成核销 -7. 礼品卡状态更新为已使用 - -### 门店操作流程 -1. 打开门店核销页面 -2. 扫描用户二维码或手动输入核销码 -3. 系统验证并显示礼品卡信息 -4. 确认信息无误后点击"确认核销" -5. 完成核销,用户礼品卡状态更新 - -## 测试验证 - -### 1. 功能测试 -- **二维码生成**:验证二维码正确生成和显示 -- **核销码生成**:验证6位数字核销码的随机性 -- **扫码识别**:验证二维码能被正确解析 -- **手动输入**:验证手动输入核销码的准确性 -- **核销完成**:验证核销后状态正确更新 - -### 2. 安全测试 -- **时效性测试**:验证核销码过期机制 -- **重复使用测试**:验证核销码不能重复使用 -- **状态验证**:验证只有未使用的礼品卡能生成核销码 - -### 3. 用户体验测试 -- **界面响应**:验证各种操作的响应速度 -- **错误处理**:验证各种异常情况的处理 -- **设备兼容**:验证在不同设备上的显示效果 - -## 部署注意事项 - -### 1. 后端API -- 确保核销相关API已部署 -- 配置核销码有效期(建议15分钟) -- 设置适当的并发限制 - -### 2. 权限配置 -- 门店核销页面需要相应权限 -- 核销操作需要记录操作人信息 - -### 3. 监控告警 -- 监控核销成功率 -- 监控异常核销请求 -- 设置核销量异常告警 - -## 后续优化建议 - -1. **批量核销**:支持一次核销多张礼品卡 -2. **核销统计**:提供核销数据统计和报表 -3. **离线核销**:支持网络异常时的离线核销 -4. **核销记录**:详细的核销历史记录查询 -5. **多门店支持**:支持多门店的核销管理 diff --git a/src/user/gift/status-field-migration.md b/src/user/gift/status-field-migration.md deleted file mode 100644 index 40f067e..0000000 --- a/src/user/gift/status-field-migration.md +++ /dev/null @@ -1,237 +0,0 @@ -# 礼品卡状态字段迁移说明 - -## 概述 - -根据后端字段调整,将礼品卡的状态字段从 `useStatus` 迁移到 `status`,并更新状态值的含义。 - -## 字段变更 - -### 旧字段 (已废弃) -```typescript -useStatus?: number // 使用状态:0-可用 1-已使用 2-已过期 -``` - -### 新字段 -```typescript -status?: number // 状态:0-未使用 1-已使用 2-失效 -``` - -## 状态值映射 - -| 状态值 | 旧含义 | 新含义 | 显示文本 | 说明 | -|--------|--------|--------|----------|------| -| 0 | 可用 | 未使用 | "未使用" | 可以使用的礼品卡 | -| 1 | 已使用 | 已使用 | "已使用" | 已经使用过的礼品卡 | -| 2 | 已过期 | 失效 | "失效" | 失效的礼品卡(包括过期等情况) | - -## 修改内容 - -### 1. GiftCard 组件 (`src/components/GiftCard.tsx`) - -#### 接口定义更新 -```typescript -// 修改前 -useStatus?: number // 使用状态:0-可用 1-已使用 2-已过期 - -// 修改后 -status?: number // 状态:0-未使用 1-已使用 2-失效 -``` - -#### 状态信息函数更新 -```typescript -// 修改前 -const getStatusInfo = () => { - switch (useStatus) { - case 0: return { text: '可使用', color: 'success' } - case 1: return { text: '已使用', color: 'warning' } - case 2: return { text: '已过期', color: 'danger' } - } -} - -// 修改后 -const getStatusInfo = () => { - switch (status) { - case 0: return { text: '未使用', color: 'success' } - case 1: return { text: '已使用', color: 'warning' } - case 2: return { text: '失效', color: 'danger' } - } -} -``` - -#### 条件判断更新 -```typescript -// 所有 useStatus 相关的条件判断都改为 status -showCode: status === 0 -showUseBtn: status === 0 -className: status !== 0 ? 'disabled' : '' -``` - -### 2. 礼品卡页面 (`src/user/gift/index.tsx`) - -#### 筛选条件更新 -```typescript -// 修改前 -const getStatusFilter = () => { - switch (String(activeTab)) { - case '0': return { useStatus: 0 } // 可用 - case '1': return { useStatus: 1 } // 已使用 - case '2': return { useStatus: 2 } // 已过期 - } -} - -// 修改后 -const getStatusFilter = () => { - switch (String(activeTab)) { - case '0': return { status: 0 } // 未使用 - case '1': return { status: 1 } // 已使用 - case '2': return { status: 2 } // 失效 - } -} -``` - -#### 数据转换更新 -```typescript -// 修改前 -const transformGiftData = (gift: ShopGift) => ({ - useStatus: gift.useStatus, - showCode: gift.useStatus === 0, - showUseBtn: gift.useStatus === 0, -}) - -// 修改后 -const transformGiftData = (gift: ShopGift) => ({ - status: gift.status, - showCode: gift.status === 0, - showUseBtn: gift.status === 0, -}) -``` - -#### Tab标签更新 -```typescript -// 修改前 - - - - -// 修改后 - - - -``` - -#### 空状态文本更新 -```typescript -// 修改前 -activeTab === '0' ? "暂无可用礼品卡" : -activeTab === '1' ? "暂无已使用礼品卡" : -"暂无已过期礼品卡" - -// 修改后 -activeTab === '0' ? "暂无未使用礼品卡" : -activeTab === '1' ? "暂无已使用礼品卡" : -"暂无失效礼品卡" -``` - -### 3. 类型定义 (`src/types/giftCard.ts`) - -#### 枚举更新 -```typescript -// 修改前 -export enum UseStatus { - AVAILABLE = 0, // 可用 - USED = 1, // 已使用 - EXPIRED = 2 // 已过期 -} - -// 修改后 -export enum GiftStatus { - UNUSED = 0, // 未使用 - USED = 1, // 已使用 - INVALID = 2 // 失效 -} -``` - -#### 接口更新 -```typescript -// 修改前 -export interface GiftCardData { - useStatus?: UseStatus -} - -// 修改后 -export interface GiftCardData { - status?: GiftStatus -} -``` - -## 业务逻辑变更 - -### 显示逻辑 -1. **未使用 (status=0)**: - - 显示绿色"未使用"标签 - - 显示兑换码 - - 显示"立即使用"按钮 - - 显示过期时间提醒 - -2. **已使用 (status=1)**: - - 显示灰色"已使用"标签 - - 不显示兑换码和使用按钮 - - 显示使用时间和地址 - - 卡片呈现禁用状态 - -3. **失效 (status=2)**: - - 显示红色"失效"标签 - - 不显示兑换码和使用按钮 - - 显示状态遮罩 - - 卡片呈现禁用状态 - -### API 调用变更 -```typescript -// 修改前 -getUserGifts({ useStatus: 0 }) // 获取可用礼品卡 - -// 修改后 -getUserGifts({ status: 0 }) // 获取未使用礼品卡 -``` - -## 测试验证 - -### 测试页面 -访问 `/user/gift/status-test` 可以验证: -- 不同状态值的显示效果 -- 状态标签文本正确性 -- 按钮和兑换码的显示逻辑 -- 卡片的禁用状态 - -### 测试用例 -1. **status=0**: 显示"未使用",有兑换码和使用按钮 -2. **status=1**: 显示"已使用",显示使用时间,无按钮 -3. **status=2**: 显示"失效",有状态遮罩,无按钮 - -## 兼容性说明 - -### 数据兼容 -- 如果后端同时返回 `useStatus` 和 `status`,优先使用 `status` -- 建议后端逐步迁移,确保数据一致性 - -### 前端兼容 -- 前端已完全切换到 `status` 字段 -- 不再处理 `useStatus` 字段 -- 所有相关逻辑都已更新 - -## 部署检查清单 - -- [ ] 后端 API 返回 `status` 字段而非 `useStatus` -- [ ] 状态值含义正确:0未使用 1已使用 2失效 -- [ ] Tab标签显示正确文本 -- [ ] 状态标签显示正确文本 -- [ ] 筛选功能使用正确的字段名 -- [ ] 空状态提示文本正确 -- [ ] 测试页面验证通过 - -## 注意事项 - -1. **数据一致性**:确保后端和前端对状态值的理解一致 -2. **用户体验**:状态文本更改可能需要用户适应 -3. **API 文档**:更新相关 API 文档,说明字段变更 -4. **监控告警**:关注迁移后的错误日志和用户反馈 diff --git a/src/user/gift/status-test.tsx b/src/user/gift/status-test.tsx deleted file mode 100644 index bc4f1f2..0000000 --- a/src/user/gift/status-test.tsx +++ /dev/null @@ -1,219 +0,0 @@ -import React from 'react' -import { View, Text } from '@tarojs/components' -import GiftCard from '@/components/GiftCard' -import { ShopGift } from '@/api/shop/shopGift/model' - -const StatusTest: React.FC = () => { - // 测试不同状态的礼品卡 - const testGifts: ShopGift[] = [ - { - id: 1, - name: '未使用礼品卡', - goodsName: '杜尔伯特草原奶香牛上脑(2kg,分4小包)', - goodsImage: 'https://img.alicdn.com/imgextra/i1/2206571109/O1CN01QZxQJJ1Uw8QZxQJJ_!!2206571109.jpg', - description: '未使用状态的礼品卡', - code: 'UNUSED1234567890', - goodsId: 101, - faceValue: '200', - type: 10, - status: 0, // 未使用 - expireTime: '2024-12-31 23:59:59', - instructions: '适用于实物商品兑换', - contactInfo: '400-800-8888' - }, - { - id: 2, - name: '已使用礼品卡', - goodsName: '星巴克经典拿铁咖啡券', - goodsImage: 'https://img.alicdn.com/imgextra/i2/2206571109/O1CN01ABC123_!!2206571109.jpg', - description: '已使用状态的礼品卡', - code: 'USED001234567890', - goodsId: 102, - faceValue: '100', - type: 20, - status: 1, // 已使用 - useTime: '2024-08-15 14:30:00', - useLocation: '星巴克王府井店', - instructions: '适用于虚拟商品兑换', - contactInfo: '400-800-8888' - }, - { - id: 3, - name: '失效礼品卡', - goodsName: '海底捞4人套餐券', - goodsImage: 'https://img.alicdn.com/imgextra/i3/2206571109/O1CN01DEF456_!!2206571109.jpg', - description: '失效状态的礼品卡', - code: 'INVALID1234567890', - goodsId: 103, - faceValue: '300', - type: 30, - status: 2, // 失效 - expireTime: '2024-07-31 23:59:59', - instructions: '适用于服务类商品兑换', - contactInfo: '400-800-8888' - } - ] - - // 转换数据格式 - const transformGiftData = (gift: ShopGift) => { - return { - id: gift.id || 0, - name: gift.name || '礼品卡', - goodsName: gift.goodsName, - description: gift.description || gift.instructions, - code: gift.code, - goodsImage: gift.goodsImage, - faceValue: gift.faceValue, - type: gift.type, - status: gift.status, // 使用 status 字段 - expireTime: gift.expireTime, - useTime: gift.useTime, - useLocation: gift.useLocation, - contactInfo: gift.contactInfo, - goodsInfo: { - ...((gift.goodsName || gift.goodsId) && { - specification: `礼品卡面值:¥${gift.faceValue}`, - category: getTypeText(gift.type), - tags: [ - getTypeText(gift.type), - getStatusText(gift.status), - '测试卡片' - ].filter(Boolean), - instructions: [ - '这是状态测试卡片', - '请检查状态显示是否正确', - '不可兑换现金' - ], - notices: [ - '这是测试数据', - '请勿实际使用', - '仅用于状态测试' - ] - }) - }, - showCode: gift.status === 0, // 只有未使用状态显示兑换码 - showUseBtn: gift.status === 0, // 只有未使用状态显示使用按钮 - showDetailBtn: true, - showGoodsDetail: true, - theme: getThemeByType(gift.type), - onUse: () => console.log('使用:', gift.goodsName || gift.name), - onDetail: () => console.log('详情:', gift.goodsName || gift.name), - onClick: () => console.log('点击:', gift.goodsName || gift.name) - } - } - - const getTypeText = (type?: number): string => { - switch (type) { - case 10: return '实物礼品卡' - case 20: return '虚拟礼品卡' - case 30: return '服务礼品卡' - default: return '通用礼品卡' - } - } - - const getStatusText = (status?: number): string => { - switch (status) { - case 0: return '未使用' - case 1: return '已使用' - case 2: return '失效' - default: return '未知状态' - } - } - - const getThemeByType = (type?: number): 'gold' | 'silver' | 'bronze' | 'blue' | 'green' | 'purple' => { - switch (type) { - case 10: return 'gold' - case 20: return 'blue' - case 30: return 'green' - default: return 'purple' - } - } - - const getExpectedBehavior = (status?: number): string => { - switch (status) { - case 0: return '显示兑换码和使用按钮' - case 1: return '显示使用时间,无兑换码和使用按钮' - case 2: return '显示失效状态,无兑换码和使用按钮' - default: return '未知行为' - } - } - - return ( - - {/* 页面标题 */} - - - 礼品卡状态字段测试 - - - 验证 status 字段替代 useStatus 字段 - - - - {/* 状态说明 */} - - 状态字段说明: - - • status=0 (未使用) → 显示"未使用"标签 - • status=1 (已使用) → 显示"已使用"标签 - • status=2 (失效) → 显示"失效"标签 - - - - {/* 修改说明 */} - - 字段修改说明: - - ✅ useStatus 字段已废弃 - ✅ 使用 status 字段替代 - ✅ 状态文本更新:可用→未使用,已过期→失效 - ✅ Tab标签文本同步更新 - - - - {/* 礼品卡列表 */} - - {testGifts.map((gift, index) => ( - - - - 测试 {index + 1}: status={gift.status} → {getStatusText(gift.status)} - - - 预期行为: {getExpectedBehavior(gift.status)} - - - - - ))} - - - {/* 验证清单 */} - - 验证清单: - - □ status=0 的卡片显示"未使用"标签 - □ status=0 的卡片显示兑换码和使用按钮 - □ status=1 的卡片显示"已使用"标签 - □ status=1 的卡片显示使用时间 - □ status=1 的卡片不显示兑换码和使用按钮 - □ status=2 的卡片显示"失效"标签 - □ status=2 的卡片有状态遮罩 - □ 所有非0状态的卡片都有disabled样式 - - - - {/* API 参数说明 */} - - API 参数更新: - - • 筛选参数:useStatus → status - • 返回字段:useStatus → status - • 状态值:0未使用 1已使用 2失效 - - - - ) -} - -export default StatusTest diff --git a/src/user/gift/tab-switch-fix.md b/src/user/gift/tab-switch-fix.md deleted file mode 100644 index 34e9e04..0000000 --- a/src/user/gift/tab-switch-fix.md +++ /dev/null @@ -1,198 +0,0 @@ -# Tab切换状态传值修复说明 - -## 问题描述 - -用户反馈:点击"未使用"标签时,显示的却是"已使用"状态的礼品卡,说明Tab切换时传递的状态值不正确。 - -## 问题分析 - -经过代码检查,发现可能的问题点: - -1. **异步状态更新问题**:`handleTabChange` 中使用 `setTimeout` 延迟执行,可能导致状态更新不及时 -2. **API参数接口混乱**:`ShopGiftParam` 接口中同时存在 `status` 和 `useStatus` 字段 -3. **状态获取时机问题**:`getStatusFilter()` 可能获取到的是旧的 `activeTab` 值 - -## 修复方案 - -### 1. 优化Tab切换逻辑 - -**修改前**: -```typescript -const handleTabChange = (value: string | number) => { - setActiveTab(value) - setPage(1) - setList([]) - setHasMore(true) - // 延迟执行reload,确保状态更新完成 - setTimeout(() => { - reload(true) - }, 100) -} -``` - -**修改后**: -```typescript -const handleTabChange = (value: string | number) => { - console.log('Tab切换到:', value) - setActiveTab(value) - setPage(1) - setList([]) - setHasMore(true) - - // 直接传递状态值,避免异步状态更新问题 - const statusFilter = getStatusFilterByValue(value) - console.log('状态过滤条件:', statusFilter) - - // 立即加载数据 - loadGiftsByStatus(statusFilter) -} -``` - -### 2. 新增辅助函数 - -```typescript -// 根据传入的值获取状态过滤条件 -const getStatusFilterByValue = (value: string | number) => { - switch (String(value)) { - case '0': return { status: 0 } // 未使用 - case '1': return { status: 1 } // 已使用 - case '2': return { status: 2 } // 失效 - default: return {} - } -} - -// 根据状态过滤条件加载礼品卡 -const loadGiftsByStatus = async (statusFilter: any) => { - setLoading(true) - try { - const res = await getUserGifts({ - page: 1, - limit: 10, - userId: Taro.getStorageSync('UserId'), - ...statusFilter - }) - console.log('API返回数据:', res?.list) - if (res && res.list) { - setList(res.list) - setHasMore(res.list.length === 10) - setPage(2) - } else { - setList([]) - setHasMore(false) - } - } catch (error) { - console.error('获取礼品卡失败:', error) - Taro.showToast({ - title: '获取礼品卡失败', - icon: 'error' - }) - } finally { - setLoading(false) - } -} -``` - -### 3. 清理API接口定义 - -**修改前**: -```typescript -export interface ShopGiftParam extends PageParam { - // 状态筛选 - status?: number; - // 使用状态筛选 - useStatus?: number; // 冗余字段,容易造成混乱 -} -``` - -**修改后**: -```typescript -export interface ShopGiftParam extends PageParam { - // 状态筛选 (0未使用 1已使用 2失效) - status?: number; - // 移除了 useStatus 字段 -} -``` - -### 4. 增强调试功能 - -在关键函数中添加了 `console.log` 调试信息: -```typescript -console.log('Tab切换到:', value) -console.log('状态过滤条件:', statusFilter) -console.log('API返回数据:', res?.list) -``` - -## 修改的文件 - -1. **`src/user/gift/index.tsx`** - - 优化 `handleTabChange` 函数 - - 新增 `getStatusFilterByValue` 函数 - - 新增 `loadGiftsByStatus` 函数 - - 增强调试日志 - -2. **`src/api/shop/shopGift/model/index.ts`** - - 移除 `ShopGiftParam` 接口中的 `useStatus` 字段 - - 明确 `status` 字段的含义 - -3. **新增测试文件** - - `src/user/gift/debug-tab.tsx` - Tab切换调试页面 - - `src/user/gift/api-test.tsx` - API参数测试页面 - -## 测试验证 - -### 1. 调试页面测试 -访问 `/user/gift/debug-tab` 可以: -- 模拟Tab切换操作 -- 查看实时的状态变化 -- 验证数据显示是否正确 - -### 2. API参数测试 -访问 `/user/gift/api-test` 可以: -- 直接测试API调用 -- 验证 `status` 参数传递 -- 检查返回数据的状态一致性 - -### 3. 实际功能测试 -在主页面 `/user/gift/index` 中: -- 点击不同Tab标签 -- 查看控制台调试信息 -- 验证显示的数据状态是否正确 - -## 预期效果 - -修复后的预期效果: - -1. **Tab切换立即生效**: - - 点击"未使用"显示 `status=0` 的礼品卡 - - 点击"已使用"显示 `status=1` 的礼品卡 - - 点击"失效"显示 `status=2` 的礼品卡 - -2. **状态显示一致**: - - Tab标签文本与显示的数据状态一致 - - 不再出现点击"未使用"显示"已使用"数据的问题 - -3. **调试信息清晰**: - - 控制台输出详细的状态切换信息 - - 便于排查问题和验证修复效果 - -## 回滚方案 - -如果修复后出现问题,可以: - -1. **恢复原有的 `handleTabChange` 函数** -2. **保留 `setTimeout` 延迟执行逻辑** -3. **在 `ShopGiftParam` 中恢复 `useStatus` 字段** - -## 注意事项 - -1. **后端兼容性**:确保后端API支持 `status` 参数筛选 -2. **数据一致性**:确保后端返回的数据中 `status` 字段值正确 -3. **缓存清理**:如有必要,清理相关的缓存数据 -4. **用户体验**:修复后用户操作应该更加流畅和准确 - -## 后续优化 - -1. **错误处理**:增强API调用失败时的错误处理 -2. **加载状态**:优化Tab切换时的加载状态显示 -3. **性能优化**:考虑添加数据缓存机制 -4. **用户反馈**:收集用户使用反馈,持续优化体验 diff --git a/src/user/gift/test.tsx b/src/user/gift/test.tsx deleted file mode 100644 index 51318bc..0000000 --- a/src/user/gift/test.tsx +++ /dev/null @@ -1,130 +0,0 @@ -import React from 'react' -import { View } from '@tarojs/components' -import GiftCard from '@/components/GiftCard' -import { ShopGift } from '@/api/shop/shopGift/model' - -const GiftCardTest: React.FC = () => { - // 模拟礼品卡数据,包含商品名称和图片 - const mockGiftData: ShopGift = { - id: 1, - name: '星巴克礼品卡', - goodsName: '星巴克咖啡礼品卡(电子版)', // 商品名称 - goodsImage: 'https://img.alicdn.com/imgextra/i1/2206571109/O1CN01QZxQJJ1Uw8QZxQJJ_!!2206571109.jpg', // 商品图片 - description: '享受醇香咖啡时光,适用于全国星巴克门店', - code: 'SB2024001234567890', - goodsId: 101, - faceValue: '100', - type: 20, // 虚拟礼品卡 - useStatus: 0, // 可用 - expireTime: '2024-12-31 23:59:59', - instructions: '请在有效期内使用,出示兑换码即可使用', - contactInfo: '400-800-8888', - createTime: '2024-08-01 10:00:00' - } - - // 转换数据格式 - const transformGiftData = (gift: ShopGift) => { - return { - id: gift.id || 0, - name: gift.goodsName || gift.name || '礼品卡', // 优先显示商品名称 - description: gift.description || gift.instructions, - code: gift.code, - goodsImage: gift.goodsImage, // 商品图片 - faceValue: gift.faceValue, - type: gift.type, - useStatus: gift.useStatus, - expireTime: gift.expireTime, - contactInfo: gift.contactInfo, - // 添加商品信息 - goodsInfo: { - ...(gift.goodsId && { - specification: `礼品卡面值:¥${gift.faceValue}`, - category: getTypeText(gift.type), - tags: [ - getTypeText(gift.type), - gift.useStatus === 0 ? '可使用' : gift.useStatus === 1 ? '已使用' : '已过期', - '全国通用', - '即买即用' - ].filter(Boolean), - instructions: gift.instructions ? [gift.instructions] : [ - '请在有效期内使用', - '出示兑换码即可使用', - '不可兑换现金', - '可用于购买任意饮品和食品' - ], - notices: [ - '礼品卡一经使用不可退换', - '请妥善保管兑换码', - '如有疑问请联系客服', - '部分特殊商品可能不适用' - ] - }) - }, - showCode: gift.useStatus === 0, - showUseBtn: gift.useStatus === 0, - showDetailBtn: true, - showGoodsDetail: true, - theme: 'green' as const, - onUse: () => console.log('使用礼品卡'), - onDetail: () => console.log('查看详情') - } - } - - const getTypeText = (type?: number): string => { - switch (type) { - case 10: return '实物礼品卡' - case 20: return '虚拟礼品卡' - case 30: return '服务礼品卡' - default: return '礼品卡' - } - } - - // 多个测试数据 - const testGifts: ShopGift[] = [ - { - ...mockGiftData, - id: 1, - goodsName: '星巴克咖啡礼品卡(电子版)', - goodsImage: 'https://img.alicdn.com/imgextra/i1/2206571109/O1CN01QZxQJJ1Uw8QZxQJJ_!!2206571109.jpg' - }, - { - ...mockGiftData, - id: 2, - goodsName: '麦当劳优惠券套餐', - goodsImage: 'https://img.alicdn.com/imgextra/i2/2206571109/O1CN01ABC123_!!2206571109.jpg', - faceValue: '50', - type: 20, - useStatus: 0 - }, - { - ...mockGiftData, - id: 3, - goodsName: '海底捞火锅券', - goodsImage: 'https://img.alicdn.com/imgextra/i3/2206571109/O1CN01DEF456_!!2206571109.jpg', - faceValue: '200', - type: 30, - useStatus: 1, - useTime: '2024-08-15 19:30:00' - } - ] - - return ( - - - - 礼品卡商品信息展示测试 - - - {testGifts.map((gift, index) => ( - - - - ))} - - - ) -} - -export default GiftCardTest diff --git a/src/user/gift/usage-example.md b/src/user/gift/usage-example.md deleted file mode 100644 index 2c1a10d..0000000 --- a/src/user/gift/usage-example.md +++ /dev/null @@ -1,145 +0,0 @@ -# 礼品卡商品信息显示使用说明 - -## 概述 - -已成功优化礼品卡组件,现在可以正确显示商品名称和图片。主要改进包括: - -1. **优先显示商品名称**:`goodsName` 优先于 `name` 显示 -2. **显示商品图片**:使用 `goodsImage` 字段显示商品图片 -3. **丰富的商品信息**:包括规格、分类、标签、使用说明等 -4. **更好的用户体验**:清晰的信息层次和视觉效果 - -## 数据结构 - -### ShopGift 模型中的关键字段 - -```typescript -interface ShopGift { - id?: number; - name?: string; // 礼品卡名称 - goodsName?: string; // 商品名称(优先显示) - goodsImage?: string; // 商品图片 - goodsId?: number; // 关联商品ID - description?: string; // 礼品卡描述 - faceValue?: string; // 面值 - type?: number; // 类型(10实物 20虚拟 30服务) - useStatus?: number; // 状态(0可用 1已使用 2已过期) - // ... 其他字段 -} -``` - -## 代码实现 - -### 1. 数据转换函数 - -在 `src/user/gift/index.tsx` 中的 `transformGiftData` 函数已经优化: - -```typescript -const transformGiftData = (gift: ShopGift): GiftCardProps => { - return { - id: gift.id || 0, - name: gift.goodsName || gift.name || '礼品卡', // 优先显示商品名称 - description: gift.description || gift.instructions, - code: gift.code, - goodsImage: gift.goodsImage, // 商品图片 - faceValue: gift.faceValue, - type: gift.type, - useStatus: gift.useStatus, - expireTime: gift.expireTime, - useTime: gift.useTime, - useLocation: gift.useLocation, - contactInfo: gift.contactInfo, - // 添加商品信息 - goodsInfo: { - ...(gift.goodsId && { - specification: `礼品卡面值:¥${gift.faceValue}`, - category: getTypeText(gift.type), - tags: [ - getTypeText(gift.type), - gift.useStatus === 0 ? '可使用' : gift.useStatus === 1 ? '已使用' : '已过期' - ].filter(Boolean), - instructions: gift.instructions ? [gift.instructions] : [ - '请在有效期内使用', - '出示兑换码即可使用', - '不可兑换现金' - ], - notices: [ - '礼品卡一经使用不可退换', - '请妥善保管兑换码', - '如有疑问请联系客服' - ] - }) - }, - showCode: gift.useStatus === 0, - showUseBtn: gift.useStatus === 0, - showDetailBtn: true, - showGoodsDetail: true, // 显示商品详情 - theme: getThemeByType(gift.type), - onUse: () => handleUseGift(gift), - onDetail: () => handleGiftDetail(gift) - } -} -``` - -### 2. 类型文本获取函数 - -```typescript -const getTypeText = (type?: number): string => { - switch (type) { - case 10: return '实物礼品卡' - case 20: return '虚拟礼品卡' - case 30: return '服务礼品卡' - default: return '礼品卡' - } -} -``` - -## 显示效果 - -### 商品信息展示包括: - -1. **基础信息** - - 商品名称(优先显示) - - 商品图片 - - 礼品卡面值 - - 商品分类 - -2. **详细信息** - - 商品规格 - - 商品标签 - - 使用说明 - - 注意事项 - -3. **状态信息** - - 使用状态标识 - - 过期时间提醒 - - 兑换码显示 - -## 测试验证 - -可以使用测试页面验证显示效果: - -```bash -# 访问测试页面 -/user/gift/test -``` - -测试页面包含了不同类型和状态的礼品卡示例,可以验证: -- 商品名称正确显示 -- 商品图片正常加载 -- 商品信息完整展示 -- 不同状态的样式效果 - -## 注意事项 - -1. **图片加载**:确保 `goodsImage` 字段包含有效的图片URL -2. **数据完整性**:建议在后端确保 `goodsName` 和 `goodsImage` 字段有值 -3. **兼容性**:保持对旧数据的兼容,当 `goodsName` 为空时使用 `name` 字段 -4. **性能优化**:大量礼品卡列表时注意图片懒加载 - -## 后续优化建议 - -1. **图片优化**:添加图片懒加载和占位符 -2. **缓存机制**:对商品信息进行本地缓存 -3. **错误处理**:添加图片加载失败的降级处理 -4. **用户体验**:添加骨架屏和加载状态 diff --git a/src/user/gift/use.tsx b/src/user/gift/use.tsx index 7e5bc05..ead0f40 100644 --- a/src/user/gift/use.tsx +++ b/src/user/gift/use.tsx @@ -127,7 +127,6 @@ const GiftCardUse = () => { goodsImage: gift.goodsImage, faceValue: gift.faceValue, type: gift.type, - useStatus: gift.useStatus, expireTime: gift.expireTime, useTime: gift.useTime, useLocation: gift.useLocation, diff --git a/src/user/store/verification.tsx b/src/user/store/verification.tsx index cee10c0..d144158 100644 --- a/src/user/store/verification.tsx +++ b/src/user/store/verification.tsx @@ -303,10 +303,10 @@ const StoreVerification: React.FC = () => { 操作说明: - 1. 用户出示礼品卡二维码 - 2. 点击"扫描二维码"进行扫码 - 3. 或手动输入用户提供的核销码 - 4. 验证成功后点击"确认核销"完成 + 1. 用户出示礼品卡二维码 + 2. 点击"扫描二维码"进行扫码 + 3. 或手动输入用户提供的核销码 + 4. 验证成功后点击"确认核销"完成