yeg
2026-09-17 dd22571b369970b35ca6c48f32010e2876b43d25
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { getApiEndpoint } from '../config/api.uts'
import { getCurrentStoreId } from './session.uts'
import { request, HttpError } from './http.uts'
 
export type VerificationScanResult = {
    verificationId: string
    credentialType: string
    status: string
    title: string
    message: string
    canVerify: boolean
    orderNo: string
    customerName: string
    customerMobile: string
    cardLevel: string
    subsidyAmount: number
    freeStayTotalCount: number
    freeStayRemainingCount: number
    benefitText: string
}
 
export type VerificationConfirmResult = {
    verified: boolean
    verifyNo: string
    status: string
    message: string
    verifiedAt: string
}
 
const localError = (code: string, message: string): HttpError => ({
    code: code,
    message: message,
    statusCode: 0,
    traceId: ''
})
 
export const scanVerificationCode = (
    rawCode: string,
    onSuccess: (result: VerificationScanResult, traceId: string) => void,
    onError: (error: HttpError) => void
): (() => void) => {
    const code = rawCode.trim()
    if (code.length == 0) {
        onError(localError('EMPTY_SCAN_RESULT', '未识别到有效二维码,请重新扫描'))
        return () => {}
    }
    const storeId = getCurrentStoreId()
    if (storeId.length == 0) {
        onError(localError('STORE_CONTEXT_MISSING', '缺少当前门店信息,请重新登录后再试'))
        return () => {}
    }
 
    return request<any>({
        path: getApiEndpoint('verificationScan'),
        method: 'POST',
        data: {
            scanResult: code,
            storeId: storeId
        }
    }, (data: any, traceId: string) => {
        if (data == null) {
            onError({ code: 'INVALID_SCAN_RESPONSE', message: '核验响应为空,请重新扫描', statusCode: 200, traceId: traceId })
            return
        }
        const verificationId = data.verificationId != null ? data.verificationId as string : ''
        const status = data.status != null ? data.status as string : ''
        let canVerify = false
        if (data.canVerify != null) {
            canVerify = data.canVerify as boolean
        } else {
            canVerify = verificationId.length > 0 || status == 'available' || status == 'pending'
        }
        const result: VerificationScanResult = {
            verificationId: verificationId,
            credentialType: data.credentialType != null ? data.credentialType as string : '',
            status: status,
            title: data.title != null ? data.title as string : (canVerify ? '核验通过' : '当前二维码不可核销'),
            message: data.message != null ? data.message as string : (data.reason != null ? data.reason as string : (canVerify ? '二维码有效,可继续确认核销' : '请确认二维码状态后重新扫描')),
            canVerify: canVerify,
            orderNo: data.orderNo != null ? data.orderNo as string : '',
            customerName: data.customerName != null ? data.customerName as string : '',
            customerMobile: data.customerMobile != null ? data.customerMobile as string : '',
            cardLevel: data.cardLevel != null ? data.cardLevel as string : '',
            subsidyAmount: data.subsidyAmount != null ? Number(data.subsidyAmount) : 0,
            freeStayTotalCount: data.freeStayTotalCount != null ? Number(data.freeStayTotalCount) : 0,
            freeStayRemainingCount: data.freeStayRemainingCount != null ? Number(data.freeStayRemainingCount) : 0,
            benefitText: data.benefitText != null ? '' + data.benefitText : ''
        }
        onSuccess(result, traceId)
    }, onError)
}
 
/** 免费入住券核销:不涉及支付,只扣券次数。订单核销走 confirmMerchantOrderVerification。 */
export const confirmVerificationCode = (
    verificationId: string,
    idempotencyKey: string,
    onSuccess: (result: VerificationConfirmResult, traceId: string) => void,
    onError: (error: HttpError) => void
): (() => void) => request<VerificationConfirmResult>({
    path: getApiEndpoint('verificationFreeStayConfirm'),
    method: 'POST',
    idempotencyKey: idempotencyKey,
    data: { verificationId: verificationId }
}, onSuccess, onError)
 
/**
 * 手输 6 位数字核销码之后的确认核销。
 *
 * 这条路不能复用订单核销接口:数字码的扫码答复刻意不返回订单号(6 位只有 100 万空间,返回归属
 * 等于给枚举一张映射表),所以客户端拿不到单号;服务端从这次扫码尝试反查订单再核销。
 */
export const confirmNumericVerificationCode = (
    verificationId: string,
    idempotencyKey: string,
    onSuccess: (result: any, traceId: string) => void,
    onError: (error: HttpError) => void
): (() => void) => request<any>({
    path: getApiEndpoint('verificationNumericConfirm'),
    method: 'POST',
    idempotencyKey: idempotencyKey,
    data: { verificationId: verificationId }
}, onSuccess, onError)