完善下单逻辑及其ui展示,修复支付倒计时显示错误bug
This commit is contained in:
172
utils/orderStatus.uts
Normal file
172
utils/orderStatus.uts
Normal file
@@ -0,0 +1,172 @@
|
||||
export type UnifiedOrderSource = 'goods' | 'service'
|
||||
|
||||
export type OrderStatusSource = {
|
||||
source?: UnifiedOrderSource | string
|
||||
order_status: number
|
||||
payment_status: number
|
||||
pay_expire_at: string
|
||||
created_at: string
|
||||
cancel_reason: string
|
||||
}
|
||||
|
||||
export const ORDER_STATUS_PENDING = 1
|
||||
export const ORDER_STATUS_PAID_OR_SHIPPING = 2
|
||||
export const ORDER_STATUS_RECEIVING = 3
|
||||
export const ORDER_STATUS_COMPLETED = 4
|
||||
export const ORDER_STATUS_CANCELLED = 5
|
||||
export const ORDER_STATUS_REFUNDING = 6
|
||||
export const ORDER_STATUS_REFUNDED = 7
|
||||
export const ORDER_STATUS_TIMEOUT_LEGACY = 8
|
||||
|
||||
export const PAYMENT_STATUS_UNPAID = 1
|
||||
export const PAYMENT_STATUS_PAID = 2
|
||||
export const PAYMENT_STATUS_PARTIAL_REFUND = 3
|
||||
export const PAYMENT_STATUS_REFUNDED = 4
|
||||
export const PAYMENT_STATUS_TIMEOUT = 5
|
||||
|
||||
export const ORDER_PAY_TIMEOUT_SECONDS = 10 * 60
|
||||
export const ORDER_TIMEOUT_CANCEL_REASON = '支付超时自动取消'
|
||||
|
||||
function parseDateMs(value: string): number {
|
||||
if (value == '') {
|
||||
return 0
|
||||
}
|
||||
const date = new Date(value)
|
||||
if (isNaN(date.getTime())) {
|
||||
return 0
|
||||
}
|
||||
return date.getTime()
|
||||
}
|
||||
|
||||
function containsTimeoutReason(cancelReason: string): boolean {
|
||||
return cancelReason.indexOf('超时') >= 0
|
||||
}
|
||||
|
||||
function getNormalizedSource(order: OrderStatusSource): UnifiedOrderSource {
|
||||
if (order.source == 'service') {
|
||||
return 'service'
|
||||
}
|
||||
return 'goods'
|
||||
}
|
||||
|
||||
function isPendingSourceOrder(order: OrderStatusSource): boolean {
|
||||
return order.order_status == ORDER_STATUS_PENDING && order.payment_status == PAYMENT_STATUS_UNPAID
|
||||
}
|
||||
|
||||
export function getOrderDeadlineMs(order: OrderStatusSource): number {
|
||||
const payExpireAtMs = parseDateMs(order.pay_expire_at)
|
||||
if (payExpireAtMs > 0) {
|
||||
return payExpireAtMs
|
||||
}
|
||||
const createdAtMs = parseDateMs(order.created_at)
|
||||
if (createdAtMs > 0) {
|
||||
return createdAtMs + ORDER_PAY_TIMEOUT_SECONDS * 1000
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
export function getRemainingSeconds(order: OrderStatusSource): number {
|
||||
const deadlineMs = getOrderDeadlineMs(order)
|
||||
if (deadlineMs <= 0) {
|
||||
return 0
|
||||
}
|
||||
const diff = Math.floor((deadlineMs - Date.now()) / 1000)
|
||||
return diff > 0 ? diff : 0
|
||||
}
|
||||
|
||||
export function getUnifiedDisplayState(order: OrderStatusSource): string {
|
||||
const source = getNormalizedSource(order)
|
||||
const deadlineMs = getOrderDeadlineMs(order)
|
||||
const hasExpiredByDeadline = order.order_status == ORDER_STATUS_PENDING && deadlineMs > 0 && deadlineMs <= Date.now()
|
||||
|
||||
if (source == 'service') {
|
||||
if (order.order_status == ORDER_STATUS_PENDING && order.payment_status == PAYMENT_STATUS_UNPAID && !hasExpiredByDeadline && !containsTimeoutReason(order.cancel_reason)) {
|
||||
return 'pending_pay'
|
||||
}
|
||||
if (order.order_status == ORDER_STATUS_TIMEOUT_LEGACY || order.payment_status == PAYMENT_STATUS_TIMEOUT || containsTimeoutReason(order.cancel_reason)) {
|
||||
return 'cancelled'
|
||||
}
|
||||
if (hasExpiredByDeadline) {
|
||||
return 'expired'
|
||||
}
|
||||
if (order.order_status == 2 || order.order_status == 3 || order.order_status == 4) {
|
||||
return 'processing'
|
||||
}
|
||||
if (order.order_status == ORDER_STATUS_COMPLETED) {
|
||||
return 'completed'
|
||||
}
|
||||
if (order.order_status == ORDER_STATUS_REFUNDING || order.order_status == ORDER_STATUS_REFUNDED) {
|
||||
return 'refund'
|
||||
}
|
||||
return 'unknown'
|
||||
}
|
||||
|
||||
if (order.order_status == ORDER_STATUS_PENDING && order.payment_status == PAYMENT_STATUS_UNPAID && !hasExpiredByDeadline && !containsTimeoutReason(order.cancel_reason)) {
|
||||
return 'pending_pay'
|
||||
}
|
||||
if (order.order_status == ORDER_STATUS_CANCELLED || order.order_status == ORDER_STATUS_TIMEOUT_LEGACY || order.payment_status == PAYMENT_STATUS_TIMEOUT || containsTimeoutReason(order.cancel_reason)) {
|
||||
return 'cancelled'
|
||||
}
|
||||
if (hasExpiredByDeadline) {
|
||||
return 'expired'
|
||||
}
|
||||
if (order.order_status == ORDER_STATUS_PAID_OR_SHIPPING || order.order_status == ORDER_STATUS_RECEIVING) {
|
||||
return 'processing'
|
||||
}
|
||||
if (order.order_status == ORDER_STATUS_COMPLETED) {
|
||||
return 'completed'
|
||||
}
|
||||
if (order.order_status == ORDER_STATUS_REFUNDING || order.order_status == ORDER_STATUS_REFUNDED) {
|
||||
return 'refund'
|
||||
}
|
||||
return 'unknown'
|
||||
}
|
||||
|
||||
export function isOrderPayExpired(order: OrderStatusSource): boolean {
|
||||
const displayState = getUnifiedDisplayState(order)
|
||||
return displayState == 'cancelled' || displayState == 'expired'
|
||||
}
|
||||
|
||||
export function isPendingPayOrder(order: OrderStatusSource): boolean {
|
||||
return getUnifiedDisplayState(order) == 'pending_pay' && isPendingSourceOrder(order)
|
||||
}
|
||||
|
||||
export function getOrderDisplayStatus(order: OrderStatusSource): string {
|
||||
const displayState = getUnifiedDisplayState(order)
|
||||
if (displayState == 'pending_pay') {
|
||||
return 'pending'
|
||||
}
|
||||
if (displayState == 'cancelled' || displayState == 'expired') {
|
||||
return 'cancelled'
|
||||
}
|
||||
if (displayState == 'processing') {
|
||||
return 'shipping'
|
||||
}
|
||||
if (displayState == 'completed') {
|
||||
return 'completed'
|
||||
}
|
||||
if (displayState == 'refund') {
|
||||
return 'refund'
|
||||
}
|
||||
return 'unknown'
|
||||
}
|
||||
|
||||
function pad2(value: number): string {
|
||||
return value < 10 ? '0' + value : '' + value
|
||||
}
|
||||
|
||||
export function formatCountdownHM(seconds: number): string {
|
||||
const safeSeconds = seconds > 0 ? seconds : 0
|
||||
const totalMinutes = Math.floor(safeSeconds / 60)
|
||||
const hours = Math.floor(totalMinutes / 60)
|
||||
const minutes = totalMinutes % 60
|
||||
return pad2(hours) + '时' + pad2(minutes) + '分钟'
|
||||
}
|
||||
|
||||
export function formatCountdownHMS(seconds: number): string {
|
||||
const safeSeconds = seconds > 0 ? seconds : 0
|
||||
const hours = Math.floor(safeSeconds / 3600)
|
||||
const minutes = Math.floor((safeSeconds % 3600) / 60)
|
||||
const remainSeconds = safeSeconds % 60
|
||||
return pad2(hours) + ':' + pad2(minutes) + ':' + pad2(remainSeconds)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user