diff --git a/components/supadb/aksupa.uts b/components/supadb/aksupa.uts
index c107e8b8..3254a1c1 100644
--- a/components/supadb/aksupa.uts
+++ b/components/supadb/aksupa.uts
@@ -364,12 +364,23 @@ export class AkSupaQueryBuilder {
}
}
if (total == 0) {
- if (typeof res['count'] == 'number') {
- total = res['count'] as number ?? 0;
+ // 使用 JSON 序列化访问 res 对象
+ const resStr = JSON.stringify(res)
+ const resParsed = JSON.parse(resStr)
+ if (resParsed != null) {
+ const resObj = resParsed as UTSJSONObject
+ const countVal = resObj.getNumber('count')
+ if (countVal != null) {
+ total = countVal
+ } else if (Array.isArray(resdata)) {
+ total = resdata.length
+ } else {
+ total = 0
+ }
} else if (Array.isArray(resdata)) {
- total = resdata.length;
+ total = resdata.length
} else {
- total = 0;
+ total = 0
}
}
if (!hasmore) hasmore = (page * limit) < total; // 如果是 head 模式,只返回 count 信息
diff --git a/pages/mall/consumer/chat copy.uvue b/pages/mall/consumer/chat copy.uvue
new file mode 100644
index 00000000..62f43c61
--- /dev/null
+++ b/pages/mall/consumer/chat copy.uvue
@@ -0,0 +1,783 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 客服 小美 已接入,请描述您的问题
+
+
+
+
+ 今天 14:30
+
+
+
+
+
+
+
+
+ {{ headerTitle }}
+
+ {{ message.content }}
+ {{ message.time }}
+
+
+
+
+
+
+
+
+ {{ message.content }}
+ {{ message.time }}
+
+
+
+
+
+
+
+
+
+
+
+ 😊
+ 📷
+ ➕
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ emoji }}
+
+
+
+
+
+
+
+
+
diff --git a/pages/mall/consumer/chat.uvue b/pages/mall/consumer/chat.uvue
index 6b551cc5..62f43c61 100644
--- a/pages/mall/consumer/chat.uvue
+++ b/pages/mall/consumer/chat.uvue
@@ -17,10 +17,13 @@
@@ -39,13 +42,13 @@
v-for="message in messages"
:key="message.id"
:class="['message-item', message.type]"
- :id="'msg-' + message.id"
+ :id="message.viewId"
>
@@ -67,7 +70,7 @@
@@ -127,6 +130,7 @@ import { getCurrentUser } from '@/utils/store.uts'
type UiChatMessage = {
id: string
+ viewId: string
type: string
content: string
time: string
@@ -141,19 +145,39 @@ const scrollToView = ref('')
const currentUserId = ref('')
const merchantId = ref('') // 商家ID
const headerTitle = ref('在线客服')
+const merchantAvatar = ref('/static/default-shop.png') // 商家头像
const navPaddingTop = ref('30px') // 默认值,包含状态栏高度+原有内边距
+const isInitialLoading = ref(true)
let realtimeChannel: AkSupaRealtimeChannel | null = null
// 模拟表情列表
const emojiList = ['😊', '😂', '🤣', '😍', '😘', '🥰', '😭', '😡', '👍', '👏', '🙏', '🎉', '❤️', '🔥', '⭐']
-function scrollToBottom(): void {
- nextTick(() => {
- if (messages.value.length > 0) {
- const lastMsgId = messages.value[messages.value.length - 1].id
- scrollToView.value = 'msg-' + lastMsgId
- }
- })
+function scrollToBottom() : void {
+ if (messages.value.length === 0) return
+
+ // 获取最后一条消息的 ID
+ const lastMsg = messages.value[messages.value.length - 1]
+ const targetId = 'msg-' + lastMsg.id
+
+ // 关键点:在 UVue 安卓端,直接连续赋值可能被合并。
+ // 我们先清除 ID,然后在下一帧赋值,确保 scroll-view 监听到变化。
+ scrollToView.value = ''
+
+ // 增加多次尝试,确保在 DOM 彻底完成渲染(包含由于高度计算引起的多次排版)后定位。
+ setTimeout(() => {
+ scrollToView.value = targetId
+ console.log('[scrollToBottom] 发起第一次滚动定位:', targetId)
+
+ // 二次校准:针对长消息或图片导致的高度变化
+ setTimeout(() => {
+ scrollToView.value = ''
+ setTimeout(() => {
+ scrollToView.value = targetId
+ console.log('[scrollToBottom] 二次校准完成:', targetId)
+ }, 50)
+ }, 100)
+ }, 300)
}
function getCurrentTime(): string {
@@ -167,14 +191,12 @@ function setupRealtimeSubscription(): void {
console.log('开始建立聊天实时订阅...')
console.log('当前用户ID:', currentUserId.value, '商家ID:', merchantId.value)
- const filter = ({
- event: 'INSERT',
- schema: 'public',
- table: 'ml_chat_messages'
- } as UTSJSONObject)
-
- realtimeChannel = supa.channel('public:ml_chat_messages')
- .on('postgres_changes', filter, (payload: any) => {
+ realtimeChannel = supa.channel('chat-messages-' + Date.now().toString())
+ .on('postgres_changes', {
+ event: 'INSERT',
+ schema: 'public',
+ table: 'ml_chat_messages'
+ }, (payload: any) => {
console.log('=== 收到实时订阅回调 ===')
const payloadObj = (payload instanceof UTSJSONObject) ? (payload as UTSJSONObject) : (JSON.parse(JSON.stringify(payload ?? {})) as UTSJSONObject)
const newMsgAny = payloadObj.get('new')
@@ -228,8 +250,12 @@ function setupRealtimeSubscription(): void {
const date = new Date(createdAt)
const timeStr = `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`
+ // 生成安全的 viewId
+ const safeViewId = 'msg_' + msgId.replace(/[^a-zA-Z0-9]/g, '_')
+
const incomingMsg: UiChatMessage = {
id: msgId,
+ viewId: safeViewId,
type: isMyMessage ? 'sent' : 'received',
content: content,
time: timeStr
@@ -253,40 +279,96 @@ function setupRealtimeSubscription(): void {
}
async function loadChatHistory(): Promise {
- let rawMsgs: ChatMessage[] = []
+ let rawMsgs : ChatMessage[] = []
- if (merchantId.value != '') {
- rawMsgs = await supabaseService.getChatMessages(merchantId.value)
- } else {
- console.warn("No merchant ID provided for chat")
- return
- }
+ if (merchantId.value != '') {
+ rawMsgs = await supabaseService.getChatMessages(merchantId.value)
+ } else {
+ console.warn("No merchant ID provided for chat")
+ return
+ }
- // 使用 for 循环替代 map
- const uiMessages: UiChatMessage[] = []
- for (let i = rawMsgs.length - 1; i >= 0; i--) {
- const m = rawMsgs[i]
- const date = new Date(m.created_at ?? new Date().toISOString())
- const timeStr = `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`
+ // 确保时间顺序是升序(旧的在前,新的在后)
+ // Supabase 返回的消息如果是降序,我们需要 reverse 过来显示
+ const sortedRawMsgs = rawMsgs.sort((a, b) => {
+ const timeA = new Date(a.created_at ?? '').getTime()
+ const timeB = new Date(b.created_at ?? '').getTime()
+ return timeA - timeB
+ })
- const sender = m.sender_id ?? ''
- const msgType = (currentUserId.value != '' && sender == currentUserId.value) ? 'sent' : 'received'
- const rawId = (m.id ?? '').toString()
- const msgId = rawId != '' ? rawId : Date.now().toString() + i.toString()
+ const uiMessages : UiChatMessage[] = []
+ for (let i = 0; i < sortedRawMsgs.length; i++) {
+ const m = sortedRawMsgs[i]
+ const date = new Date(m.created_at ?? new Date().toISOString())
+ const timeStr = `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`
+
+ const sender = m.sender_id ?? ''
+ const msgType = (currentUserId.value != '' && sender == currentUserId.value) ? 'sent' : 'received'
+ const rawId = (m.id ?? '').toString()
+ const msgId = rawId != '' ? rawId : Date.now().toString() + i.toString()
+ const safeViewId = 'msg_' + msgId.replace(/[^a-zA-Z0-9]/g, '_')
+
+ const uiMsg : UiChatMessage = {
+ id: msgId,
+ viewId: safeViewId,
+ type: msgType,
+ content: m.content ?? '',
+ time: timeStr
+ }
+ uiMessages.push(uiMsg)
+ }
+ messages.value = uiMessages
+
+ if (isInitialLoading.value) {
+ // 增加一点初始化延迟,等待 scroll-view 渲染就绪
+ setTimeout(() => {
+ scrollToBottom()
+ isInitialLoading.value = false
+ }, 500)
+ }
+}
+
+function onScrollToUpper(e: any): void {
+ console.log('[onScrollToUpper] 触发加载历史记录')
+}
+
+async function loadMerchantInfo(): Promise {
+ if (merchantId.value == '') return
+
+ try {
+ const response = await supa
+ .from('ml_shops')
+ .select('shop_logo, shop_name')
+ .eq('merchant_id', merchantId.value)
+ .limit(1)
+ .execute()
- const uiMsg: UiChatMessage = {
- id: msgId,
- type: msgType,
- content: m.content ?? '',
- time: timeStr
+ if (response.error != null) {
+ console.error('[loadMerchantInfo] 获取商家信息失败:', response.error)
+ return
}
- uiMessages.push(uiMsg)
+
+ const rawData = response.data
+ if (rawData == null) return
+
+ const rawList = rawData as any[]
+ if (rawList.length == 0) return
+
+ const shopData = rawList[0]
+ const shopObj = JSON.parse(JSON.stringify(shopData)) as UTSJSONObject
+
+ const logo = shopObj.getString('shop_logo')
+ if (logo != null && logo != '') {
+ merchantAvatar.value = logo
+ }
+
+ const name = shopObj.getString('shop_name')
+ if (name != null && name != '' && headerTitle.value == '在线客服') {
+ headerTitle.value = name
+ }
+ } catch (e) {
+ console.error('[loadMerchantInfo] 获取商家信息异常:', e)
}
- messages.value = uiMessages
-
- setTimeout(() => {
- scrollToBottom()
- }, 100)
}
// 生命周期
@@ -320,6 +402,7 @@ onMounted(() => {
})
}
+ loadMerchantInfo()
loadChatHistory()
setupRealtimeSubscription()
})
@@ -340,15 +423,16 @@ const sendMessage = async () => {
// 发送到 Supabase
if (merchantId.value != '') {
- // 不使用乐观更新,等待实时订阅推送
- // 这样可以确保多端同步
+ console.log('[sendMessage] 开始发送消息到:', merchantId.value)
const success = await supabaseService.sendMessage(merchantId.value, content)
+ console.log('[sendMessage] 发送结果:', success)
if (!success) {
uni.showToast({
title: '发送失败',
icon: 'none'
})
}
+ // 不需要手动添加消息,等待实时订阅推送
}
}
@@ -438,22 +522,23 @@ const goBack = () => {
diff --git a/pages/mall/consumer/orders.uvue b/pages/mall/consumer/orders.uvue
index d6781d5a..3e3b2249 100644
--- a/pages/mall/consumer/orders.uvue
+++ b/pages/mall/consumer/orders.uvue
@@ -18,13 +18,20 @@
-
-
-
+
+
+ 全部
+
+
+
+
{{ tab.name }}
@@ -58,10 +65,15 @@
v-for="order in orders"
:key="order.id"
class="order-card"
+ @click="viewOrderDetail(order.id)"
>
-
-
-
-
-
- 商品合计
- ¥{{ order.product_amount }}
-
-
- 运费
- ¥{{ order.shipping_fee }}
-
-
- 实付款
- ¥{{ order.total_amount }}
+
+
+ {{ formatDate(order.create_time) }}
+
+ 共{{ order.products.length }}件商品 实付:
+ ¥{{ order.total_amount }}
-
+
@@ -162,24 +169,6 @@ import { ref, reactive, onMounted, computed } from 'vue'
import { onShow, onLoad, onBackPress } from '@dcloudio/uni-app'
import { supabaseService } from '@/utils/supabaseService.uts'
-// 拦截返回事件,避免跳回登录页
-onBackPress((options) => {
- if (options.from === 'navigateBack') {
- const pages = getCurrentPages()
- if (pages.length > 1) {
- const prevPage = pages[pages.length - 2]
- // 如果上一页是登录页,则重定向到个人中心
- if (prevPage.route.includes('login')) {
- uni.redirectTo({
- url: '/pages/mall/consumer/profile'
- })
- return true
- }
- }
- }
- return false
-})
-
// 定义标签页类型
type OrderTabItem = {
id: string,
@@ -206,6 +195,8 @@ type OrderItem = {
product_amount: number,
shipping_fee: number,
total_amount: number,
+ merchant_id: string,
+ shop_name: string,
products: OrderProduct[]
}
@@ -230,7 +221,10 @@ const orderTabs = ref([
{ id: 'cancelled', name: '已取消', count: 0 }
])
-// Removed Mock Data
+// 模拟状态筛选(除去"全部"后的其余标签)
+const orderTabsMobile = computed((): OrderTabItem[] => {
+ return orderTabs.value.filter((tab: OrderTabItem) => tab.id !== 'all')
+})
// 辅助函数:获取状态码
@@ -243,59 +237,98 @@ const getStatusByTab = (tabId: string): number => {
return 0
}
-// 辅助函数:解析规格文本
-const parseSpecText = (specs: any): string => {
- if (specs == null) return ''
- if (typeof specs === 'string') return specs
- // 对于对象类型,尝试转为JSON字符串或简单处理
+// 格式化规格对象为友好的文本 - 必须在 parseSpecText 之前定义
+function formatSpecObj(obj: any): string {
+ if (obj == null) return ''
+ if (typeof obj !== 'object') {
+ // 非对象类型直接返回字符串形式
+ if (typeof obj === 'string') return obj
+ if (typeof obj === 'number') return obj.toString()
+ return ''
+ }
+
try {
- return JSON.stringify(specs)
+ const objStr = JSON.stringify(obj)
+ const objParsed = JSON.parse(objStr)
+ if (objParsed == null) return ''
+
+ const specObj = objParsed as UTSJSONObject
+
+ // 使用 JSON.stringify 获取所有键
+ const specObjStr = JSON.stringify(specObj)
+ const specObjForKeys = JSON.parse(specObjStr) as UTSJSONObject
+
+ // 手动提取键值对
+ const parts: string[] = []
+
+ // 尝试获取已知字段
+ const colorVal = specObjForKeys.getString('Color')
+ if (colorVal != null && colorVal != '') {
+ parts.push('Color: ' + colorVal)
+ }
+
+ const sizeVal = specObjForKeys.getString('Size')
+ if (sizeVal != null && sizeVal != '') {
+ parts.push('Size: ' + sizeVal)
+ }
+
+ const defaultVal = specObjForKeys.getString('默认')
+ if (defaultVal != null && defaultVal != '') {
+ parts.push('默认: ' + defaultVal)
+ }
+
+ // 如果没有匹配到已知字段,尝试直接显示 JSON
+ if (parts.length === 0) {
+ // 尝试遍历对象
+ const objAny = specObjForKeys as any
+ if (objAny != null) {
+ return specObjStr.replace(/[{}"]/g, '').replace(/:/g, ': ').replace(/,/g, ' | ')
+ }
+ }
+
+ return parts.join(' | ')
} catch (e) {
return ''
}
}
+// 辅助函数:解析规格文本
+function parseSpecText(specs: any): string {
+ if (specs == null) return ''
+ if (typeof specs === 'string') {
+ // 如果是 JSON 字符串,尝试解析
+ if (specs.startsWith('{') || specs.startsWith('[')) {
+ try {
+ const parsed = JSON.parse(specs)
+ if (parsed == null) return specs
+ return formatSpecObj(parsed)
+ } catch (e) {
+ return specs
+ }
+ }
+ return specs
+ }
+ // 对于对象类型,格式化显示
+ return formatSpecObj(specs)
+}
+
// 辅助函数:更新标签计数
-const updateTabsCounts = (allOrders: any[]) => {
- // 直接重新赋值整个数组
- const tabsData = orderTabs.value
+const updateTabsCounts = (allOrders: OrderItem[]) => {
// 计算各状态数量
const countAll = allOrders.length
- const countPending = allOrders.filter((o: any) => {
- const obj = o as Record
- return obj['status'] === 1
- }).length
- const countShipping = allOrders.filter((o: any) => {
- const obj = o as Record
- return obj['status'] === 2
- }).length
- const countDelivering = allOrders.filter((o: any) => {
- const obj = o as Record
- return obj['status'] === 3
- }).length
- const countCompleted = allOrders.filter((o: any) => {
- const obj = o as Record
- return obj['status'] === 4
- }).length
- const countCancelled = allOrders.filter((o: any) => {
- const obj = o as Record
- return obj['status'] === 5
- }).length
+ const countPending = allOrders.filter((o: OrderItem) => o.status === 1).length
+ const countShipping = allOrders.filter((o: OrderItem) => o.status === 2).length
+ const countDelivering = allOrders.filter((o: OrderItem) => o.status === 3).length
+ const countCompleted = allOrders.filter((o: OrderItem) => o.status === 4).length
+ const countCancelled = allOrders.filter((o: OrderItem) => o.status === 5).length
// 更新数组元素
- const tabsArr = tabsData as any[]
- const tab0 = tabsArr[0] as Record
- tab0['count'] = countAll
- const tab1 = tabsArr[1] as Record
- tab1['count'] = countPending
- const tab2 = tabsArr[2] as Record
- tab2['count'] = countShipping
- const tab3 = tabsArr[3] as Record
- tab3['count'] = countDelivering
- const tab4 = tabsArr[4] as Record
- tab4['count'] = countCompleted
- const tab5 = tabsArr[5] as Record
- tab5['count'] = countCancelled
+ orderTabs.value[0].count = countAll
+ orderTabs.value[1].count = countPending
+ orderTabs.value[2].count = countShipping
+ orderTabs.value[3].count = countDelivering
+ orderTabs.value[4].count = countCompleted
+ orderTabs.value[5].count = countCancelled
}
// 辅助函数:按标签筛选订单
@@ -317,69 +350,124 @@ const loadOrders = async () => {
try {
// Fetch all orders from Supabase (status=0)
const fetchedOrders = await supabaseService.getOrders(0)
+ console.log('[loadOrders] 获取到订单数量:', fetchedOrders.length)
// Map to View Model
- const mappedOrders: any[] = []
+ const mappedOrders: OrderItem[] = []
for (let i = 0; i < fetchedOrders.length; i++) {
const order = fetchedOrders[i]
- const orderObj = order as Record
- const items = orderObj['ml_order_items'] as any[]
- const productsList: any[] = []
+ // 使用 JSON 序列化转换
+ const orderStr = JSON.stringify(order)
+ const orderParsed = JSON.parse(orderStr)
+ if (orderParsed == null) continue
+ const orderObj = orderParsed as UTSJSONObject
- if (items != null) {
- for (let j = 0; j < items.length; j++) {
- const item = items[j]
- const itemObj = item as Record
- const specRaw = itemObj['specifications']
- const specText = specRaw != null ? parseSpecText(specRaw) : ''
- productsList.push({
- id: itemObj['product_id'],
- name: itemObj['product_name'],
- price: itemObj['price'],
- image: itemObj['image_url'] ?? '/static/default-product.png',
- spec: specText,
- quantity: itemObj['quantity']
- })
+ const itemsRaw = orderObj.get('ml_order_items')
+ const productsList: OrderProduct[] = []
+
+ console.log('[loadOrders] 订单商品数据:', itemsRaw)
+
+ if (itemsRaw != null) {
+ // 先检查是否为数组
+ if (Array.isArray(itemsRaw)) {
+ const items = itemsRaw as any[]
+ console.log('[loadOrders] 商品数量:', items.length)
+ for (let j = 0; j < items.length; j++) {
+ const item = items[j]
+ const itemStr = JSON.stringify(item)
+ const itemParsed = JSON.parse(itemStr)
+ if (itemParsed == null) continue
+ const itemObj = itemParsed as UTSJSONObject
+
+ const specRaw = itemObj.get('specifications')
+ const specText = specRaw != null ? parseSpecText(specRaw) : ''
+
+ const productId = itemObj.getString('product_id')
+ const productName = itemObj.getString('product_name')
+ const price = itemObj.getNumber('price')
+ const imageUrl = itemObj.getString('image_url')
+ const quantity = itemObj.getNumber('quantity')
+
+ console.log('[loadOrders] 商品:', productName, '图片:', imageUrl, '规格:', specText)
+
+ const productItem: OrderProduct = {
+ id: productId ?? '',
+ name: productName ?? '未知商品',
+ price: price ?? 0,
+ image: imageUrl ?? '/static/default-product.png',
+ spec: specText,
+ quantity: quantity ?? 1
+ }
+ productsList.push(productItem)
+ }
}
}
- mappedOrders.push({
- id: orderObj['id'],
- order_no: orderObj['order_no'],
- status: orderObj['order_status'],
- create_time: orderObj['created_at'],
- product_amount: orderObj['product_amount'] ?? 0,
- shipping_fee: orderObj['shipping_fee'] ?? 0,
- total_amount: orderObj['total_amount'] ?? orderObj['paid_amount'] ?? 0,
+ const orderId = orderObj.getString('id')
+ const orderNo = orderObj.getString('order_no')
+ const orderStatus = orderObj.getNumber('order_status')
+ const createdAt = orderObj.getString('created_at')
+ const productAmount = orderObj.getNumber('product_amount')
+ const shippingFee = orderObj.getNumber('shipping_fee')
+ const totalAmount = orderObj.getNumber('total_amount')
+ const paidAmount = orderObj.getNumber('paid_amount')
+ const merchantId = orderObj.getString('merchant_id')
+
+ // 从关联查询的 ml_shops 表获取店铺名称
+ let shopName = '自营店铺'
+ const shopsRaw = orderObj.get('ml_shops')
+ if (shopsRaw != null) {
+ const shopStr = JSON.stringify(shopsRaw)
+ const shopParsed = JSON.parse(shopStr)
+ if (shopParsed != null) {
+ const shopObj = shopParsed as UTSJSONObject
+ const shopNameFromDb = shopObj.getString('shop_name')
+ if (shopNameFromDb != null && shopNameFromDb != '') {
+ shopName = shopNameFromDb
+ }
+ }
+ } else if (merchantId != null && merchantId != '') {
+ shopName = '商家店铺'
+ }
+
+ console.log('[loadOrders] 订单号:', orderNo, '店铺:', shopName, '商品数:', productsList.length)
+
+ // 如果没有商品数据,添加一个占位商品
+ if (productsList.length === 0) {
+ const placeholderProduct: OrderProduct = {
+ id: 'placeholder',
+ name: '订单商品',
+ price: totalAmount ?? paidAmount ?? 0,
+ image: '/static/default-product.png',
+ spec: '',
+ quantity: 1
+ }
+ productsList.push(placeholderProduct)
+ }
+
+ const mappedOrder: OrderItem = {
+ id: orderId ?? '',
+ order_no: orderNo ?? '',
+ status: orderStatus ?? 1,
+ create_time: createdAt ?? '',
+ product_amount: productAmount ?? 0,
+ shipping_fee: shippingFee ?? 0,
+ total_amount: totalAmount ?? paidAmount ?? 0,
+ merchant_id: merchantId ?? '',
+ shop_name: shopName,
products: productsList
- })
+ }
+ mappedOrders.push(mappedOrder)
}
- // Sort by created_at desc
- mappedOrders.sort((a: any, b: any) => {
- const aObj = a as Record
- const bObj = b as Record
- const timeA = new Date(aObj['create_time'] as string).getTime()
- const timeB = new Date(bObj['create_time'] as string).getTime()
+ // Sort by created_at desc - 直接使用 OrderItem 类型访问属性
+ mappedOrders.sort((a: OrderItem, b: OrderItem) => {
+ const timeA = new Date(a.create_time).getTime()
+ const timeB = new Date(b.create_time).getTime()
return timeB - timeA
})
- // 将 mappedOrders 转换为 OrderItem[] 类型
- const typedOrders: OrderItem[] = []
- for (let i = 0; i < mappedOrders.length; i++) {
- const mo = mappedOrders[i] as Record
- typedOrders.push({
- id: mo['id'] as string,
- order_no: mo['order_no'] as string,
- status: mo['status'] as number,
- create_time: mo['create_time'] as string,
- product_amount: mo['product_amount'] as number,
- shipping_fee: mo['shipping_fee'] as number,
- total_amount: mo['total_amount'] as number,
- products: mo['products'] as OrderProduct[]
- })
- }
- allOrdersList.value = typedOrders
+ allOrdersList.value = mappedOrders
// Update tab counts
updateTabsCounts(mappedOrders)
@@ -397,14 +485,17 @@ const loadOrders = async () => {
// 生命周期
onLoad((options) => {
- if (options['status'] != null) {
- const status = options['status'] as string
+ if (options == null) return
+ const statusVal = options['status']
+ if (statusVal != null) {
+ const status = statusVal as string
if (['all', 'pending', 'shipping', 'delivering', 'completed', 'cancelled'].includes(status)) {
activeTab.value = status
}
}
- if (options['type'] != null) {
- const type = options['type'] as string
+ const typeVal = options['type']
+ if (typeVal != null) {
+ const type = typeVal as string
if (type === 'pending') activeTab.value = 'pending'
else if (type === 'shipped') activeTab.value = 'delivering' // 映射到待收货
else if (type === 'review') activeTab.value = 'completed' // 映射到已完成
@@ -500,6 +591,8 @@ const getStatusText = (status: number): string => {
if (status == 3) return '待收货'
if (status == 4) return '已完成'
if (status == 5) return '已取消'
+ if (status == 6) return '退款中'
+ if (status == 7) return '已退款'
return '未知状态'
}
@@ -510,6 +603,8 @@ const getStatusClass = (status: number): string => {
if (status == 3) return 'status-delivering'
if (status == 4) return 'status-completed'
if (status == 5) return 'status-cancelled'
+ if (status == 6) return 'status-refunding'
+ if (status == 7) return 'status-refunded'
return 'status-unknown'
}
@@ -705,10 +800,12 @@ const goShopping = () => {