consumer模块完成度95%,能编译在安卓端运行,在解决数据获取和页面布局问题
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 售后列表 -->
|
||||
<scroll-view class="refund-content" scroll-y @scrolltolower="loadMore">
|
||||
<scroll-view class="refund-content" direction="vertical" @scrolltolower="loadMore">
|
||||
<!-- 空状态 -->
|
||||
<view v-if="refunds.length === 0 && !isLoading" class="empty-refunds">
|
||||
<text class="empty-icon">🔄</text>
|
||||
@@ -58,7 +58,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 进度时间线 -->
|
||||
<view v-if="refund.status_history?.length > 0" class="timeline">
|
||||
<view v-if="refund.status_history != null && refund.status_history.length > 0" class="timeline">
|
||||
<view v-for="(step, index) in getTimelineSteps(refund)"
|
||||
:key="index"
|
||||
class="timeline-step">
|
||||
@@ -116,7 +116,7 @@ type RefundProductInfo = {
|
||||
type RefundOrderItem = {
|
||||
id: string
|
||||
product_name: string
|
||||
sku_specifications: any
|
||||
sku_specifications: any | null
|
||||
price: number
|
||||
quantity: number
|
||||
product?: RefundProductInfo
|
||||
@@ -157,27 +157,17 @@ const currentPage = ref<number>(1)
|
||||
const pageSize = ref<number>(15)
|
||||
const hasMore = ref<boolean>(true)
|
||||
|
||||
// 监听标签页变化
|
||||
watch(activeTab, () => {
|
||||
resetData()
|
||||
loadRefunds()
|
||||
})
|
||||
const getCurrentUserId = (): string => {
|
||||
return supabaseService.getCurrentUserId() ?? ''
|
||||
}
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
loadRefunds()
|
||||
loadTabCounts()
|
||||
})
|
||||
|
||||
// 重置数据
|
||||
const resetData = () => {
|
||||
refunds.value = []
|
||||
currentPage.value = 1
|
||||
hasMore.value = true
|
||||
}
|
||||
|
||||
// 加载售后数据
|
||||
const loadRefunds = async (loadMore: boolean = false) => {
|
||||
const loadRefunds = async (loadMore: boolean): Promise<void> => {
|
||||
if (isLoading.value || (!hasMore.value && loadMore)) {
|
||||
return
|
||||
}
|
||||
@@ -197,46 +187,66 @@ const loadRefunds = async (loadMore: boolean = false) => {
|
||||
|
||||
let statusList: number[] = []
|
||||
if (activeTab.value === 'processing') {
|
||||
statusList = [1, 2] // 待处理和处理中
|
||||
statusList = [1, 2]
|
||||
} else if (activeTab.value === 'completed') {
|
||||
statusList = [3, 4, 5] // 已完成、已取消、已拒绝
|
||||
statusList = [3, 4, 5]
|
||||
}
|
||||
|
||||
const rawData = await supabaseService.getRefunds(statusList, page, pageSize.value)
|
||||
|
||||
// Map data to UI structure (RefundType)
|
||||
const newRefunds = rawData.map((item: any): RefundType => {
|
||||
const orderObj: any = item['order'] ?? {}
|
||||
const dbItems: any[] = (orderObj['ml_order_items'] as any[]) ?? []
|
||||
const uiItems = dbItems.map((di: any) : RefundOrderItem => ({
|
||||
id: di['id'] ?? '',
|
||||
product_name: di['product_name'] ?? '',
|
||||
sku_specifications: di['specifications'],
|
||||
price: 0,
|
||||
quantity: di['quantity'] ?? 1,
|
||||
product: { images: [di['image_url'] ?? '/static/default-product.png'] }
|
||||
}))
|
||||
const newRefunds: Array<RefundType> = []
|
||||
for (let i: number = 0; i < rawData.length; i++) {
|
||||
const item = rawData[i] as UTSJSONObject
|
||||
const orderObjRaw = item.get('order')
|
||||
const orderObj = (orderObjRaw != null) ? (orderObjRaw as UTSJSONObject) : (new UTSJSONObject())
|
||||
const dbItemsRaw = orderObj.get('ml_order_items')
|
||||
const dbItems = (dbItemsRaw != null) ? (dbItemsRaw as any[]) : []
|
||||
|
||||
return {
|
||||
id: item['id'],
|
||||
user_id: item['user_id'],
|
||||
order_id: item['order_id'],
|
||||
refund_no: item['refund_no'],
|
||||
refund_type: item['refund_type'],
|
||||
refund_reason: item['refund_reason'],
|
||||
refund_amount: Number(item['refund_amount']),
|
||||
status: item['status'],
|
||||
// Handle missing timeline by defaulting or leaving empty
|
||||
status_history: (item['status_history'] as RefundStatusHistoryItem[]) ?? [],
|
||||
created_at: item.created_at,
|
||||
const uiItems: Array<RefundOrderItem> = []
|
||||
for (let j: number = 0; j < dbItems.length; j++) {
|
||||
const di = dbItems[j] as UTSJSONObject
|
||||
const imgRaw = di.get('image_url')
|
||||
const imgUrl = (imgRaw != null) ? (imgRaw as string) : '/static/default-product.png'
|
||||
const productInfo: RefundProductInfo = {
|
||||
images: [imgUrl]
|
||||
} as RefundProductInfo
|
||||
|
||||
const specRaw = di.get('specifications')
|
||||
const specifications = (specRaw != null) ? (specRaw as any) : null
|
||||
const orderItem: RefundOrderItem = {
|
||||
id: di.getString('id') ?? '',
|
||||
product_name: di.getString('product_name') ?? '',
|
||||
sku_specifications: specifications,
|
||||
price: 0,
|
||||
quantity: di.getNumber('quantity') ?? 1,
|
||||
product: productInfo
|
||||
} as RefundOrderItem
|
||||
uiItems.push(orderItem)
|
||||
}
|
||||
|
||||
const statusHistoryRaw = item.get('status_history')
|
||||
const statusHistory = (statusHistoryRaw != null) ? (statusHistoryRaw as RefundStatusHistoryItem[]) : []
|
||||
|
||||
const refundItem: RefundType = {
|
||||
id: item.getString('id') ?? '',
|
||||
user_id: item.getString('user_id') ?? '',
|
||||
order_id: item.getString('order_id') ?? '',
|
||||
refund_no: item.getString('refund_no') ?? '',
|
||||
refund_type: item.getNumber('refund_type') ?? 1,
|
||||
refund_reason: item.getString('refund_reason') ?? '',
|
||||
refund_amount: item.getNumber('refund_amount') ?? 0,
|
||||
status: item.getNumber('status') ?? 1,
|
||||
status_history: statusHistory,
|
||||
created_at: item.getString('created_at') ?? '',
|
||||
order: {
|
||||
id: item.order_id,
|
||||
order_no: orderObj.order_no,
|
||||
created_at: orderObj.created_at,
|
||||
id: item.getString('order_id') ?? '',
|
||||
order_no: orderObj.getString('order_no') ?? '',
|
||||
created_at: orderObj.getString('created_at') ?? '',
|
||||
order_items: uiItems
|
||||
}
|
||||
} as RefundOrderInfo
|
||||
} as RefundType
|
||||
})
|
||||
newRefunds.push(refundItem)
|
||||
}
|
||||
|
||||
if (loadMore) {
|
||||
refunds.value.push(...newRefunds)
|
||||
@@ -254,57 +264,44 @@ const loadRefunds = async (loadMore: boolean = false) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 加载标签页计数
|
||||
const loadTabCounts = async () => {
|
||||
const userId = getCurrentUserId()
|
||||
if (userId == '') return
|
||||
|
||||
try {
|
||||
const { count, error } = await supa
|
||||
.from('refunds')
|
||||
.select('*', { count: 'exact' })
|
||||
.eq('user_id', userId)
|
||||
.in('status', [1, 2])
|
||||
|
||||
if (error !== null) {
|
||||
console.error('加载计数失败:', error)
|
||||
return
|
||||
}
|
||||
|
||||
tabCounts.value.processing = count ?? 0
|
||||
const processingRefunds = await supabaseService.getRefunds([1, 2], 1, 100)
|
||||
tabCounts.value.processing = processingRefunds.length
|
||||
} catch (err) {
|
||||
console.error('加载计数异常:', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前用户ID
|
||||
const getCurrentUserId = (): string => {
|
||||
const userStore = uni.getStorageSync('userInfo')
|
||||
return userStore['id'] ?? ''
|
||||
}
|
||||
watch(activeTab, () => {
|
||||
resetData()
|
||||
loadRefunds(false)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
loadRefunds(false)
|
||||
loadTabCounts()
|
||||
})
|
||||
|
||||
// 获取状态文本
|
||||
const getStatusText = (status: number): string => {
|
||||
const statusMap: Record<number, string> = {
|
||||
1: '待处理',
|
||||
2: '处理中',
|
||||
3: '已完成',
|
||||
4: '已取消',
|
||||
5: '已拒绝'
|
||||
}
|
||||
return statusMap[status] ?? '未知状态'
|
||||
if (status === 1) return '待处理'
|
||||
if (status === 2) return '处理中'
|
||||
if (status === 3) return '已完成'
|
||||
if (status === 4) return '已取消'
|
||||
if (status === 5) return '已拒绝'
|
||||
return '未知状态'
|
||||
}
|
||||
|
||||
// 获取状态样式类
|
||||
const getStatusClass = (status: number): string => {
|
||||
const classMap: Record<number, string> = {
|
||||
1: 'status-pending',
|
||||
2: 'status-processing',
|
||||
3: 'status-completed',
|
||||
4: 'status-cancelled',
|
||||
5: 'status-rejected'
|
||||
}
|
||||
return classMap[status] ?? 'status-unknown'
|
||||
if (status === 1) return 'status-pending'
|
||||
if (status === 2) return 'status-processing'
|
||||
if (status === 3) return 'status-completed'
|
||||
if (status === 4) return 'status-cancelled'
|
||||
if (status === 5) return 'status-rejected'
|
||||
return 'status-unknown'
|
||||
}
|
||||
|
||||
// 获取商品图片
|
||||
@@ -337,45 +334,58 @@ const formatTime = (timeStr?: string): string => {
|
||||
return `${month}-${day}`
|
||||
}
|
||||
|
||||
// 获取时间线步骤
|
||||
const getTimelineSteps = (refund: RefundType): Array<any> => {
|
||||
const steps = [
|
||||
{ status: 0, title: '提交申请', time: refund.created_at },
|
||||
{ status: 1, title: '商家处理', time: '' },
|
||||
{ status: 3, title: '退款完成', time: '' }
|
||||
]
|
||||
|
||||
// 如果有状态历史,更新时间和描述
|
||||
if (refund.status_history) {
|
||||
refund.status_history.forEach(history => {
|
||||
if (history.status === 1 || history.status === 2) {
|
||||
steps[1].time = history.created_at
|
||||
steps[1].desc = history.remark
|
||||
} else if (history.status === 3) {
|
||||
steps[2].time = history.created_at
|
||||
steps[2].desc = history.remark
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 标记当前状态
|
||||
return steps.map((step, index) => ({
|
||||
...step,
|
||||
active: index === getCurrentStepIndex(refund.status),
|
||||
completed: index < getCurrentStepIndex(refund.status)
|
||||
}))
|
||||
const getCurrentStepIndex = (status: number): number => {
|
||||
if (status === 1) return 0
|
||||
if (status === 2) return 1
|
||||
if (status === 3) return 2
|
||||
if (status === 4) return 0
|
||||
if (status === 5) return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
// 获取当前步骤索引
|
||||
const getCurrentStepIndex = (status: number): number => {
|
||||
switch (status) {
|
||||
case 1: return 0 // 待处理
|
||||
case 2: return 1 // 处理中
|
||||
case 3: return 2 // 已完成
|
||||
case 4: return 0 // 已取消
|
||||
case 5: return 1 // 已拒绝
|
||||
default: return 0
|
||||
type TimelineStepType = {
|
||||
status: number,
|
||||
title: string,
|
||||
time: string,
|
||||
active: boolean,
|
||||
completed: boolean,
|
||||
desc: string
|
||||
}
|
||||
|
||||
const getTimelineSteps = (refund: RefundType): Array<TimelineStepType> => {
|
||||
const steps: Array<TimelineStepType> = [
|
||||
{ status: 0, title: '提交申请', time: refund.created_at, active: false, completed: false, desc: '' },
|
||||
{ status: 1, title: '商家处理', time: '', active: false, completed: false, desc: '' },
|
||||
{ status: 3, title: '退款完成', time: '', active: false, completed: false, desc: '' }
|
||||
]
|
||||
|
||||
if (refund.status_history != null) {
|
||||
for (let i: number = 0; i < refund.status_history.length; i++) {
|
||||
const history = refund.status_history[i]
|
||||
if (history.status === 1 || history.status === 2) {
|
||||
steps[1].time = history.created_at ?? ''
|
||||
steps[1].desc = history.remark ?? ''
|
||||
} else if (history.status === 3) {
|
||||
steps[2].time = history.created_at ?? ''
|
||||
steps[2].desc = history.remark ?? ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const currentStepIndex = getCurrentStepIndex(refund.status)
|
||||
const result: Array<TimelineStepType> = []
|
||||
for (let i: number = 0; i < steps.length; i++) {
|
||||
const step = steps[i]
|
||||
result.push({
|
||||
status: step.status,
|
||||
title: step.title,
|
||||
time: step.time,
|
||||
desc: step.desc,
|
||||
active: i === currentStepIndex,
|
||||
completed: i < currentStepIndex
|
||||
})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// 切换标签页
|
||||
@@ -397,45 +407,42 @@ const viewOrder = (orderId: string) => {
|
||||
})
|
||||
}
|
||||
|
||||
// 取消退款申请
|
||||
const doCancelRefund = async (refund: RefundType) => {
|
||||
try {
|
||||
const result = await supabaseService.createRefund({
|
||||
id: refund.id,
|
||||
status: 4
|
||||
} as any)
|
||||
|
||||
if (result.success) {
|
||||
refund.status = 4
|
||||
loadTabCounts()
|
||||
uni.showToast({
|
||||
title: '已取消',
|
||||
icon: 'success'
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '取消失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('取消退款失败:', err)
|
||||
uni.showToast({
|
||||
title: '取消失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const cancelRefund = (refund: RefundType) => {
|
||||
uni.showModal({
|
||||
title: '取消申请',
|
||||
content: '确定要取消这个退款申请吗?',
|
||||
success: async (res) => {
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
try {
|
||||
const { error } = await supa
|
||||
.from('refunds')
|
||||
.update({
|
||||
status: 4, // 已取消
|
||||
status_history: [...(refund.status_history ?? []), {
|
||||
status: 4,
|
||||
remark: '用户取消申请',
|
||||
created_at: new Date().toISOString()
|
||||
}]
|
||||
})
|
||||
.eq('id', refund.id)
|
||||
|
||||
if (error !== null) {
|
||||
throw error
|
||||
}
|
||||
|
||||
refund.status = 4
|
||||
loadTabCounts() // 重新加载计数
|
||||
|
||||
uni.showToast({
|
||||
title: '已取消',
|
||||
icon: 'success'
|
||||
})
|
||||
|
||||
} catch (err) {
|
||||
console.error('取消退款失败:', err)
|
||||
uni.showToast({
|
||||
title: '取消失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
doCancelRefund(refund)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -455,41 +462,45 @@ const reviewRefund = (refund: RefundType) => {
|
||||
})
|
||||
}
|
||||
|
||||
// 删除记录
|
||||
const doDeleteRefund = async (refund: RefundType) => {
|
||||
try {
|
||||
const result = await supabaseService.deleteRefund(refund.id)
|
||||
|
||||
if (result) {
|
||||
const newRefunds: Array<RefundType> = []
|
||||
for (let i: number = 0; i < refunds.value.length; i++) {
|
||||
if (refunds.value[i].id !== refund.id) {
|
||||
newRefunds.push(refunds.value[i])
|
||||
}
|
||||
}
|
||||
refunds.value = newRefunds
|
||||
|
||||
uni.showToast({
|
||||
title: '删除成功',
|
||||
icon: 'success'
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '删除失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('删除记录失败:', err)
|
||||
uni.showToast({
|
||||
title: '删除失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const deleteRefund = (refund: RefundType) => {
|
||||
uni.showModal({
|
||||
title: '删除记录',
|
||||
content: '确定要删除这个售后记录吗?',
|
||||
success: async (res) => {
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
try {
|
||||
const { error } = await supa
|
||||
.from('refunds')
|
||||
.delete()
|
||||
.eq('id', refund.id)
|
||||
|
||||
if (error !== null) {
|
||||
throw error
|
||||
}
|
||||
|
||||
const index = refunds.value.findIndex(r => r.id === refund.id)
|
||||
if (index !== -1) {
|
||||
refunds.value.splice(index, 1)
|
||||
refunds.value = [...refunds.value]
|
||||
}
|
||||
|
||||
uni.showToast({
|
||||
title: '删除成功',
|
||||
icon: 'success'
|
||||
})
|
||||
|
||||
} catch (err) {
|
||||
console.error('删除记录失败:', err)
|
||||
uni.showToast({
|
||||
title: '删除失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
doDeleteRefund(refund)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user