This commit is contained in:
Mrx
2026-05-28 15:22:34 +08:00
parent 6e5379080c
commit 0f0cdd67c2
7 changed files with 98 additions and 19 deletions

View File

@@ -18,8 +18,10 @@ const maskedName = computed(() => {
return name.length > 1 ? `${name[0]}${'*'.repeat(name.length - 1)}` : '*' return name.length > 1 ? `${name[0]}${'*'.repeat(name.length - 1)}` : '*'
}) })
/** 上游天远返回 { result: { status } },少数场景为顶层 status */
const status = computed(() => { const status = computed(() => {
const s = Number(p.value.status) const raw = p.value
const s = Number(raw?.status ?? raw?.result?.status)
if ([0, -1, -2, -4].includes(s)) if ([0, -1, -2, -4].includes(s))
return s return s
return null return null

View File

@@ -19,7 +19,7 @@ export const VEHICLE_API_TITLES = {
QCXG4I1Z: '车辆过户详版查询', QCXG4I1Z: '车辆过户详版查询',
QCXGGB2Q: '车辆二要素核验 V1', QCXGGB2Q: '车辆二要素核验 V1',
QCXGP00W: '车辆出险详版查询', QCXGP00W: '车辆出险详版查询',
QCXGYTS2: '车辆二要素核验 V2', QCXGYTS2: '人车核验(详版)',
QCXGGJ3A: '车辆 VIN 码查询号牌简版', QCXGGJ3A: '车辆 VIN 码查询号牌简版',
QCXGJJ2A: '车辆 VIN 码查车辆信息详版', QCXGJJ2A: '车辆 VIN 码查车辆信息详版',
QCXG5F3A: '名下车辆车牌查询 B', QCXG5F3A: '名下车辆车牌查询 B',

View File

@@ -59,9 +59,7 @@
"navigationBarTitleText": "我的", "navigationBarTitleText": "我的",
"navigationStyle": "default", "navigationStyle": "default",
"navigationBarBackgroundColor": "#ffffff", "navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black", "navigationBarTextStyle": "black"
"enableShareAppMessage": true,
"enableShareTimeline": true
} }
}, },
{ {

View File

@@ -11,9 +11,6 @@ definePage({
navigationStyle: 'default', navigationStyle: 'default',
navigationBarBackgroundColor: '#ffffff', navigationBarBackgroundColor: '#ffffff',
navigationBarTextStyle: 'black', navigationBarTextStyle: 'black',
// 微信小程序:允许使用 open-type="share" 与右上角转发
enableShareAppMessage: true,
enableShareTimeline: true,
}, },
}) })

View File

@@ -1,5 +1,5 @@
<script setup> <script setup>
import { onLoad } from '@dcloudio/uni-app' import { onLoad, onUnload } from '@dcloudio/uni-app'
import { ref } from 'vue' import { ref } from 'vue'
import { getQueryDetailByOrderId, getQueryDetailByOrderNo } from '@/api' import { getQueryDetailByOrderId, getQueryDetailByOrderNo } from '@/api'
import VehicleReportShell from '@/components/report/VehicleReportShell.vue' import VehicleReportShell from '@/components/report/VehicleReportShell.vue'
@@ -18,45 +18,87 @@ definePage({
const orderNo = ref('') const orderNo = ref('')
const orderId = ref('') const orderId = ref('')
const loading = ref(true) const loading = ref(true)
const pending = ref(false)
const errText = ref('') const errText = ref('')
const productName = ref('') const productName = ref('')
const queryParams = ref({}) const queryParams = ref({})
const rows = ref(normalizeVehicleQueryData([])) const rows = ref(normalizeVehicleQueryData([]))
let pollTimer = null
onLoad((options) => { onLoad((options) => {
orderNo.value = options?.orderNo || '' orderNo.value = options?.orderNo || ''
orderId.value = options?.orderId || '' orderId.value = options?.orderId || ''
void load() void load()
}) })
async function load() { onUnload(() => {
stopPoll()
})
function stopPoll() {
if (pollTimer) {
clearInterval(pollTimer)
pollTimer = null
}
}
function startPoll() {
if (pollTimer)
return
pollTimer = setInterval(() => {
void load({ silent: true })
}, 2000)
}
async function load(opts = {}) {
const silent = opts.silent === true
if (!orderNo.value && !orderId.value) { if (!orderNo.value && !orderId.value) {
loading.value = false loading.value = false
pending.value = false
errText.value = '缺少订单信息' errText.value = '缺少订单信息'
return return
} }
if (!silent) {
loading.value = true loading.value = true
errText.value = '' errText.value = ''
pending.value = false
}
try { try {
const res = orderId.value const res = orderId.value
? await getQueryDetailByOrderId(orderId.value) ? await getQueryDetailByOrderId(orderId.value, { skipLoading: silent })
: await getQueryDetailByOrderNo(orderNo.value) : await getQueryDetailByOrderNo(orderNo.value, { skipLoading: silent })
const parsed = parseEncryptedQueryReport(res) const parsed = parseEncryptedQueryReport(res)
productName.value = parsed.productName || '查询报告' productName.value = parsed.productName || '查询报告'
if (parsed.pending) {
pending.value = true
errText.value = parsed.msg || '报告生成中,请稍候…'
rows.value = normalizeVehicleQueryData([])
startPoll()
return
}
stopPoll()
pending.value = false
if (parsed.ok) { if (parsed.ok) {
queryParams.value = parsed.queryParams queryParams.value = parsed.queryParams
rows.value = parsed.rows rows.value = parsed.rows
if (!rows.value.length) errText.value = rows.value.length ? '' : '暂无报告模块数据'
errText.value = '暂无报告模块数据'
} }
else { else {
rows.value = normalizeVehicleQueryData([])
errText.value = parsed.msg || '加载失败' errText.value = parsed.msg || '加载失败'
} }
} }
catch { catch {
stopPoll()
pending.value = false
errText.value = '网络异常或未登录' errText.value = '网络异常或未登录'
} }
finally { finally {
if (!silent)
loading.value = false loading.value = false
} }
} }
@@ -64,9 +106,13 @@ async function load() {
<template> <template>
<view class="page-root"> <view class="page-root">
<view v-if="loading" class="state"> <view v-if="loading && !pending" class="state">
加载中 加载中
</view> </view>
<view v-else-if="pending" class="state pending">
<view class="spinner" />
<text>{{ errText || '报告生成中,请稍候…' }}</text>
</view>
<view v-else-if="errText && !rows.length" class="state"> <view v-else-if="errText && !rows.length" class="state">
{{ errText }} {{ errText }}
</view> </view>
@@ -95,6 +141,28 @@ async function load() {
color: #86909c; color: #86909c;
} }
.state.pending {
display: flex;
flex-direction: column;
align-items: center;
gap: 24rpx;
}
.spinner {
width: 64rpx;
height: 64rpx;
border: 6rpx solid #e5e6eb;
border-top-color: #1768ff;
border-radius: 50%;
animation: spin 0.9s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.content { .content {
padding: 24rpx 24rpx 48rpx; padding: 24rpx 24rpx 48rpx;
box-sizing: border-box; box-sizing: border-box;

View File

@@ -53,7 +53,8 @@ const maskedName = computed(() => {
// status: 0 一致, -1 不一致, -2 非法姓名, -4 无记录 // status: 0 一致, -1 不一致, -2 非法姓名, -4 无记录
const status = computed(() => { const status = computed(() => {
const s = props.data?.status; const raw = props.data || {};
const s = Number(raw.status ?? raw.result?.status);
if (s === 0 || s === -1 || s === -2 || s === -4) return s; if (s === 0 || s === -1 || s === -2 || s === -4) return s;
return null; return null;
}); });

View File

@@ -5,6 +5,9 @@ import { normalizeVehicleQueryData } from './vehicleReportNormalize'
* 解析 /query/example、/query/orderNo 等接口返回体。 * 解析 /query/example、/query/orderNo 等接口返回体。
* 成功时 data 为 AES 加密字符串,需解密后取 query_data。 * 成功时 data 为 AES 加密字符串,需解密后取 query_data。
*/ */
/** 与 H5 Report.vue报告生成中轮询 */
const PENDING_API_CODES = new Set([200002, 100005])
export function parseEncryptedQueryReport(apiBody) { export function parseEncryptedQueryReport(apiBody) {
if (!apiBody) if (!apiBody)
return { ok: false, msg: '无响应数据' } return { ok: false, msg: '无响应数据' }
@@ -12,6 +15,9 @@ export function parseEncryptedQueryReport(apiBody) {
if (apiBody.code === 200003) if (apiBody.code === 200003)
return { ok: false, empty: true, msg: apiBody.msg || '暂无示例报告' } return { ok: false, empty: true, msg: apiBody.msg || '暂无示例报告' }
if (PENDING_API_CODES.has(apiBody.code))
return { ok: false, pending: true, msg: apiBody.msg || '报告生成中,请稍候…' }
if (apiBody.code !== 200 || apiBody.data == null || apiBody.data === '') if (apiBody.code !== 200 || apiBody.data == null || apiBody.data === '')
return { ok: false, msg: apiBody.msg || '加载失败' } return { ok: false, msg: apiBody.msg || '加载失败' }
@@ -29,6 +35,12 @@ export function parseEncryptedQueryReport(apiBody) {
if (!payload || typeof payload !== 'object') if (!payload || typeof payload !== 'object')
return { ok: false, msg: '报告数据格式错误' } return { ok: false, msg: '报告数据格式错误' }
const queryState = String(payload.query_state || '')
if (queryState === 'pending')
return { ok: false, pending: true, msg: '报告生成中,请稍候…' }
if (queryState === 'failed')
return { ok: false, failed: true, msg: '报告生成失败' }
const rows = normalizeVehicleQueryData(payload.query_data || []) const rows = normalizeVehicleQueryData(payload.query_data || [])
return { return {
ok: true, ok: true,
@@ -36,5 +48,6 @@ export function parseEncryptedQueryReport(apiBody) {
queryParams: payload.query_params || {}, queryParams: payload.query_params || {},
rows, rows,
createTime: payload.create_time || null, createTime: payload.create_time || null,
queryState,
} }
} }