| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- import { resolveFileUrl } from '@/utils/image'
- import { formatPrice } from '@/utils/format'
- import { parseCartSpecText } from '@/utils/cartSpec'
- import {
- ORDER_ACTION,
- ORDER_ACTION_LABEL,
- REVIEW_ITEM_STATUS,
- AFTERSALE_APPLY_TYPE_OPTIONS
- } from '@/constants/order'
- /** 订单级不再展示的评价按钮(改在商品行) */
- const ORDER_LEVEL_REVIEW_CODES = [ORDER_ACTION.REVIEW, ORDER_ACTION.VIEW_REVIEW]
- const GOODS_PLACEHOLDER = '/static/logo.png'
- const SHOP_PLACEHOLDER = '/static/logo.png'
- /** 后端凭证图可能是逗号拼接字符串,统一转成数组 */
- function normalizePicList(raw) {
- if (!raw) return []
- if (Array.isArray(raw)) return raw.filter(Boolean)
- if (typeof raw === 'string') {
- return raw.split(',').map((s) => s.trim()).filter(Boolean)
- }
- return []
- }
- function mapAftersaleApplyTypeText(applyType) {
- const hit = AFTERSALE_APPLY_TYPE_OPTIONS.find((opt) => opt.value === applyType)
- return hit ? hit.label : applyType || ''
- }
- function mapAftersaleStatusText(status) {
- if (status === '2') return '售后完结'
- if (status === '1') return '商家处理中'
- return status || ''
- }
- function mapAftersaleProgressText(stage) {
- if (stage === 'FINISHED') return '商家处理 → 售后完结(当前:售后完结)'
- return '商家处理 → 售后完结(当前:商家处理)'
- }
- function mapFirstItem(item) {
- if (!item) return null
- const specText = (item.goodsSpec || item.specText || '').trim() || '默认'
- return {
- orderItemId: item.itemId || item.orderItemId,
- goodsId: item.goodsId,
- goodsName: item.goodsName || '',
- displayPic: resolveFileUrl(item.goodsImage || item.mainPic) || GOODS_PLACEHOLDER,
- specText,
- specList: parseCartSpecText(specText),
- quantity: Number(item.quantity) || 1,
- unitPrice: item.unitPrice,
- priceText: formatPrice(item.unitPrice),
- reviewStatus: item.reviewStatus,
- reviewId: item.reviewId
- }
- }
- function mapOrderItemRow(row) {
- if (!row) return null
- const specText = (row.goodsSpec || row.specText || '').trim() || '默认'
- return {
- orderItemId: row.orderItemId || row.itemId,
- goodsId: row.goodsId,
- goodsName: row.goodsName || '',
- displayPic: resolveFileUrl(row.goodsImage || row.mainPic) || GOODS_PLACEHOLDER,
- specText,
- specList: parseCartSpecText(specText),
- serviceDesc: row.serviceDesc || '',
- quantity: Number(row.quantity) || 1,
- unitPrice: row.unitPrice || row.salePrice,
- priceText: formatPrice(row.unitPrice || row.salePrice),
- lineAmount: row.lineAmount || row.subtotal,
- lineAmountText: formatPrice(row.lineAmount || row.subtotal),
- buyerRemark: row.buyerRemark || '',
- reviewStatus: row.reviewStatus,
- reviewId: row.reviewId
- }
- }
- function mapActions(actions) {
- return (actions || [])
- .filter((code) => !ORDER_LEVEL_REVIEW_CODES.includes(code))
- .map((code) => ({
- code,
- label: ORDER_ACTION_LABEL[code] || code
- }))
- .filter((item) => item.label)
- }
- /** 交易成功商品行:待评价→评价,已评价→查看评价 */
- export function getItemReviewAction(item) {
- if (!item || !item.reviewStatus) return null
- if (item.reviewStatus === REVIEW_ITEM_STATUS.PENDING) {
- return {
- code: ORDER_ACTION.REVIEW,
- label: ORDER_ACTION_LABEL[ORDER_ACTION.REVIEW]
- }
- }
- if (item.reviewStatus === REVIEW_ITEM_STATUS.DONE) {
- return {
- code: ORDER_ACTION.VIEW_REVIEW,
- label: ORDER_ACTION_LABEL[ORDER_ACTION.VIEW_REVIEW]
- }
- }
- return null
- }
- /** 评价列表「待评价」:订单行展平为待评价商品行 */
- export function flattenPendingReviewItems(rows) {
- const result = []
- for (const row of rows || []) {
- const card = mapOrderListRow(row)
- if (!card) continue
- for (const item of card.items || []) {
- if (item.reviewStatus !== REVIEW_ITEM_STATUS.PENDING) continue
- result.push({
- key: `pending-${card.orderId}-${item.orderItemId}`,
- orderId: card.orderId,
- item
- })
- }
- }
- return result
- }
- /** 评价列表「已评价」行 → 紧凑卡片模型 */
- export function mapReviewDoneRow(row) {
- if (!row) return null
- const item = mapFirstItem(row.firstItem)
- const content = (row.content || '').trim()
- return {
- key: `done-${row.reviewId || row.orderId}-${item?.orderItemId || 0}`,
- reviewId: row.reviewId,
- orderId: row.orderId,
- orderItemId: item?.orderItemId,
- score: Number(row.score) || 0,
- content,
- contentBrief: trimText(content, 48, '此用户未填写评价内容'),
- reviewTime: row.reviewTime || row.createTime || '',
- item
- }
- }
- function trimText(text, maxLen, emptyFallback = '') {
- const s = (text || '').trim()
- if (!s) return emptyFallback
- if (s.length <= maxLen) return s
- return `${s.slice(0, maxLen)}…`
- }
- /** 列表行 VO → 卡片模型 */
- export function mapOrderListRow(row) {
- if (!row) return null
- const rawItems = Array.isArray(row.items) && row.items.length
- ? row.items
- : row.firstItem
- ? [row.firstItem]
- : []
- const items = rawItems.map(mapFirstItem).filter(Boolean)
- const firstItem = items[0] || mapFirstItem(row.firstItem)
- return {
- orderId: row.orderId,
- orderNo: row.orderNo || '',
- orderStatus: row.orderStatus,
- statusText: row.orderStatusText || '',
- shopId: row.shopId,
- shopName: row.shopName || '',
- shopAvatar: resolveFileUrl(row.shopAvatar) || SHOP_PLACEHOLDER,
- payAmount: row.payAmount,
- payAmountText: formatPrice(row.payAmount),
- goodsAmount: row.goodsAmount,
- freightAmount: row.freightAmount,
- createTime: row.createTime || '',
- itemCount: Number(row.itemCount) || items.length,
- items,
- firstItem,
- payRemainSeconds: row.payRemainSeconds,
- reviewStatus: row.reviewStatus,
- actions: mapActions(row.actions)
- }
- }
- /** 详情 VO → 页面模型 */
- export function mapOrderDetail(data) {
- if (!data) return null
- const items = (data.items || []).map(mapOrderItemRow).filter(Boolean)
- const latestTrace = data.latestTrace || null
- return {
- orderId: data.orderId,
- orderNo: data.orderNo || '',
- orderStatus: data.orderStatus,
- statusText: data.orderStatusText || '',
- payStatus: data.payStatus,
- payType: data.payType,
- payTypeText: data.payTypeText || '',
- shopId: data.shopId,
- shopName: data.shopName || '',
- shopAvatar: resolveFileUrl(data.shopAvatar) || SHOP_PLACEHOLDER,
- consigneeName: data.consigneeName || '',
- consigneeMobile: data.consigneeMobile || '',
- consigneeAddress: data.consigneeAddress || '',
- goodsAmount: data.goodsAmount,
- goodsAmountText: formatPrice(data.goodsAmount),
- freightAmount: data.freightAmount,
- freightAmountText: formatPrice(data.freightAmount),
- freightDesc: data.freightDesc || '',
- payAmount: data.payAmount,
- payAmountText: formatPrice(data.payAmount),
- createTime: data.createTime || '',
- payTime: data.payTime || '',
- payExpireTime: data.payExpireTime || '',
- payRemainSeconds: data.payRemainSeconds,
- finishTime: data.finishTime || '',
- shipTime: data.shipTime || '',
- closeType: data.closeType,
- closeTypeText: data.closeTypeText || '',
- closeReason: data.closeReason || '',
- deliveryType: data.deliveryType,
- logisticsCompany: data.logisticsCompany || '',
- trackingNo: data.trackingNo || '',
- vehicleNo: data.vehicleNo || '',
- courierName: data.courierName || '',
- courierMobile: data.courierMobile || '',
- latestTrace: latestTrace
- ? {
- traceType: latestTrace.traceType,
- traceTime: latestTrace.traceTime || '',
- content: latestTrace.content || ''
- }
- : null,
- items,
- reviewStatus: data.reviewStatus,
- reviewId: data.reviewId,
- actions: mapActions(data.actions)
- }
- }
- /** 评价详情 */
- export function mapOrderReview(data) {
- if (!data) return null
- const pics = (data.pics || []).map((p) => resolveFileUrl(p) || p).filter(Boolean)
- return {
- score: Number(data.score) || 0,
- content: data.content || '',
- pics,
- createTime: data.createTime || '',
- replyContent: data.replyContent || '',
- replyTime: data.replyTime || ''
- }
- }
- /** 售后列表行 */
- export function mapAftersaleListRow(row) {
- if (!row) return null
- const specText = (row.goodsSpec || row.specText || '').trim() || '默认'
- return {
- aftersaleId: row.aftersaleId,
- aftersaleNo: row.aftersaleNo || '',
- aftersaleStatus: row.aftersaleStatus,
- statusText:
- row.aftersaleStatusText ||
- row.statusText ||
- mapAftersaleStatusText(row.aftersaleStatus),
- applyType: row.applyType,
- applyTypeText: row.applyTypeText || mapAftersaleApplyTypeText(row.applyType),
- applyReason: row.applyReason || '',
- applyAmount: row.applyAmount,
- applyAmountText: formatPrice(row.applyAmount),
- createTime: row.createTime || '',
- goodsName: row.goodsName || '',
- displayPic: resolveFileUrl(row.goodsImage || row.mainPic) || GOODS_PLACEHOLDER,
- specList: parseCartSpecText(specText),
- orderId: row.orderId,
- orderNo: row.orderNo || ''
- }
- }
- /** 售后详情 */
- export function mapAftersaleDetail(data) {
- if (!data) return null
- const info = data.info || data
- const specText = (info.goodsSpec || info.specText || '').trim() || '默认'
- const progressStage = data.progressStage || info.progressStage || ''
- const aftersaleStatus = info.aftersaleStatus || data.aftersaleStatus
- return {
- aftersaleId: info.aftersaleId || data.aftersaleId,
- aftersaleNo: info.aftersaleNo || data.aftersaleNo || '',
- aftersaleStatus,
- statusText:
- info.aftersaleStatusText ||
- info.statusText ||
- mapAftersaleStatusText(aftersaleStatus),
- progress: data.progress || info.progress || progressStage,
- progressText:
- data.progressText ||
- info.progressText ||
- mapAftersaleProgressText(progressStage),
- applyType: info.applyType,
- applyTypeText: info.applyTypeText || mapAftersaleApplyTypeText(info.applyType),
- applyReason: info.applyReason || '',
- returnQuantity: info.returnQuantity,
- applyAmount: info.applyAmount,
- applyAmountText: formatPrice(info.applyAmount),
- description: info.description || '',
- evidencePics: normalizePicList(info.evidencePics).map((p) => resolveFileUrl(p) || p),
- createTime: info.createTime || '',
- finishTime: info.finishTime || '',
- processResult: data.processResult || info.processResult || '',
- orderId: info.orderId,
- orderNo: info.orderNo || '',
- orderItemId: info.orderItemId,
- goodsName: info.goodsName || '',
- displayPic: resolveFileUrl(info.goodsImage || info.mainPic) || GOODS_PLACEHOLDER,
- specList: parseCartSpecText(specText),
- quantity: Number(info.quantity) || 1
- }
- }
- /** 待支付倒计时文案 */
- export function formatPayCountdown(seconds) {
- if (seconds == null || seconds <= 0) return '已超时'
- const h = Math.floor(seconds / 3600)
- const m = Math.floor((seconds % 3600) / 60)
- const s = seconds % 60
- if (h > 0) {
- return `${h}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`
- }
- return `${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`
- }
|