feat(user): 新增收货地址管理及售后申请页面

- 新增地址类型定义,增强前端地址数据结构
- 新增地址编辑页面,支持地址智能识别和定位选点功能
- 地址编辑支持省市区选择及默认地址设置
- 新增地址列表页面,支持地址展示、删除、编辑和选择功能
- 实现售后申请页面,支持选择售后类型和退款原因
- 售后申请支持商品选择、退款金额计算和凭证上传
- 新增售后详情页面,支持售后状态展示及申请取消
- 优化页面加载和用户交互体验,增加错误提示和权限处理
This commit is contained in:
2026-07-01 12:11:56 +08:00
parent bf6ed504cc
commit 1fa58040f3
636 changed files with 58878 additions and 716 deletions

104
src_bak/hooks/useCoupon.ts Normal file
View File

@@ -0,0 +1,104 @@
import { useState, useCallback } from 'react'
import {
listShopUserCoupon,
pageShopUserCoupon,
removeShopUserCoupon,
getMyAvailableCoupons,
getMyUsedCoupons,
getMyExpiredCoupons,
} from '@/api/shop/shopUserCoupon'
import type { ShopUserCoupon } from '@/api/shop/shopUserCoupon/model'
export type CouponTab = 'available' | 'used' | 'expired'
interface UseCouponReturn {
coupons: ShopUserCoupon[]
loading: boolean
tab: CouponTab
setTab: (tab: CouponTab) => void
loadCoupons: () => Promise<void>
deleteCoupon: (id: string) => Promise<boolean>
}
export function useCoupon(): UseCouponReturn {
const [coupons, setCoupons] = useState<ShopUserCoupon[]>([])
const [loading, setLoading] = useState(false)
const [tab, setTab] = useState<CouponTab>('available')
const loadCoupons = useCallback(async () => {
setLoading(true)
try {
let list: ShopUserCoupon[] = []
switch (tab) {
case 'available':
list = await getMyAvailableCoupons()
break
case 'used':
list = await getMyUsedCoupons()
break
case 'expired':
list = await getMyExpiredCoupons()
break
}
setCoupons(list || [])
} catch (error) {
console.error('Load coupons error:', error)
} finally {
setLoading(false)
}
}, [tab])
const deleteCoupon = useCallback(async (id: string): Promise<boolean> => {
try {
await removeShopUserCoupon(Number(id))
setCoupons(prev => prev.filter(c => c.id !== id))
return true
} catch {
return false
}
}, [])
return { coupons, loading, tab, setTab, loadCoupons, deleteCoupon }
}
// 获取优惠券类型文本
export function getCouponTypeText(type?: number): string {
switch (type) {
case 10: return '满减券'
case 20: return '折扣券'
case 30: return '免费券'
case 40: return '无门槛券'
case 50: return '场地使用券'
default: return '优惠券'
}
}
// 获取优惠券状态文本
export function getCouponStatusText(coupon: ShopUserCoupon): string {
if (coupon.status === 1) return '已使用'
if (coupon.status === 2 || coupon.isExpire === 1) return '已过期'
return '未使用'
}
// 格式化优惠券金额
export function formatCouponValue(coupon: ShopUserCoupon): string {
switch (coupon.type) {
case 20:
// 折扣券
return `${coupon.discount || 0}`
case 40:
// 无门槛券
return `¥${coupon.reducePrice || '0'}`
case 50:
// 场地使用券
return coupon.useCount && coupon.useCount > 0 ? `${coupon.useCount}` : '不限次'
default:
// 满减券/免费券
return `¥${coupon.reducePrice || '0'}`
}
}
// 检查优惠券是否即将过期3天内
export function isExpiringSoon(coupon: ShopUserCoupon): boolean {
return coupon.isExpiringSoon === true || (coupon.daysRemaining !== undefined && coupon.daysRemaining <= 3)
}