Files
xinlong-shop-taro/src_bak/api/shop/shopAfterSale/index.ts
赵忠林 1fa58040f3 feat(user): 新增收货地址管理及售后申请页面
- 新增地址类型定义,增强前端地址数据结构
- 新增地址编辑页面,支持地址智能识别和定位选点功能
- 地址编辑支持省市区选择及默认地址设置
- 新增地址列表页面,支持地址展示、删除、编辑和选择功能
- 实现售后申请页面,支持选择售后类型和退款原因
- 售后申请支持商品选择、退款金额计算和凭证上传
- 新增售后详情页面,支持售后状态展示及申请取消
- 优化页面加载和用户交互体验,增加错误提示和权限处理
2026-07-01 12:11:56 +08:00

155 lines
3.8 KiB
TypeScript

import request from '@/utils/request'
import type { ApiResult, PageResult } from '@/api'
// 售后类型
export type AfterSaleType = 'refund' | 'return' | 'exchange' | 'repair'
// 售后状态
export type AfterSaleStatus =
| 'pending' // 待审核
| 'approved' // 已同意
| 'rejected' // 已拒绝
| 'processing' // 处理中
| 'completed' // 已完成
| 'cancelled' // 已取消
// 售后进度记录
export interface ProgressRecord {
id: string
time: string
status: string
description: string
operator?: string
remark?: string
}
// 售后详情
export interface AfterSaleDetail {
id: string
orderId: string
orderNo: string
goodsName?: string
type: AfterSaleType
status: AfterSaleStatus
reason: string
description: string
amount: number
applyTime: string
processTime?: string
completeTime?: string
rejectReason?: string
contactPhone?: string
evidenceImages: string[]
progressRecords: ProgressRecord[]
}
// 售后申请参数
export interface AfterSaleApplyParams {
orderId: string
type: AfterSaleType
reason: string
description?: string
amount?: number
contactPhone?: string
evidenceImages?: string[]
goodsItems?: Array<{ goodsId: string; quantity: number }>
}
// 售后列表查询参数
export interface AfterSaleListParams {
page?: number
pageSize?: number
status?: AfterSaleStatus
type?: AfterSaleType
}
// 售后类型映射
export const AFTER_SALE_TYPE_MAP: Record<AfterSaleType, string> = {
refund: '退款',
return: '退货',
exchange: '换货',
repair: '维修',
}
// 售后状态映射
export const AFTER_SALE_STATUS_MAP: Record<AfterSaleStatus, string> = {
pending: '待审核',
approved: '已同意',
rejected: '已拒绝',
processing: '处理中',
completed: '已完成',
cancelled: '已取消',
}
// 格式化售后状态
export const formatAfterSaleStatus = (status: AfterSaleStatus): {
text: string
color: string
icon: string
} => {
const statusMap: Record<AfterSaleStatus, { text: string; color: string; icon: string }> = {
pending: { text: '待审核', color: 'text-orange-500', icon: '⏳' },
approved: { text: '已同意', color: 'text-green-500', icon: '✅' },
rejected: { text: '已拒绝', color: 'text-red-500', icon: '❌' },
processing: { text: '处理中', color: 'text-blue-500', icon: '🔄' },
completed: { text: '已完成', color: 'text-green-500', icon: '✅' },
cancelled: { text: '已取消', color: 'text-gray-400', icon: '⭕' },
}
return statusMap[status] || { text: status, color: 'text-gray-400', icon: '📋' }
}
/**
* 申请售后
*/
export async function applyAfterSale(data: AfterSaleApplyParams) {
const res = await request.post<ApiResult<AfterSaleDetail>>(
'/shop/shop-after-sale/apply',
data
)
if (res.code === 0) {
return res.data
}
return Promise.reject(new Error(res.message))
}
/**
* 分页查询售后列表
*/
export async function pageAfterSaleList(params: AfterSaleListParams) {
const res = await request.get<ApiResult<PageResult<AfterSaleDetail>>>(
'/shop/shop-after-sale/page',
params
)
if (res.code === 0) {
return res.data
}
return Promise.reject(new Error(res.message))
}
/**
* 查询售后详情
*/
export async function getAfterSaleDetail(id: string) {
const res = await request.get<ApiResult<AfterSaleDetail>>(
'/shop/shop-after-sale/' + id
)
if (res.code === 0 && res.data) {
return res.data
}
return Promise.reject(new Error(res.message))
}
/**
* 撤销售后申请
*/
export async function cancelAfterSale(id: string) {
const res = await request.post<ApiResult<unknown>>(
'/shop/shop-after-sale/cancel',
{ id }
)
if (res.code === 0) {
return res.message
}
return Promise.reject(new Error(res.message))
}