f
This commit is contained in:
2
.env
2
.env
@@ -7,3 +7,5 @@
|
||||
# VITE_API_BASE_URL=/api/v1
|
||||
# VITE_API_BASE_URL=http://127.0.0.1:8888/api/v1
|
||||
VITE_API_BASE_URL=https://www.tianyuancha.cn/api/v1
|
||||
# H5 站点根地址(报告分享 / webview 链接),默认由 VITE_API_BASE_URL 推导
|
||||
VITE_H5_BASE_URL=https://www.tianyuancha.cn
|
||||
|
||||
@@ -35,3 +35,9 @@ export async function postQueryService(productEn, body, requestConfig) {
|
||||
const res = await http.post(`/query/service/${enc}`, body, requestConfig)
|
||||
return res.data
|
||||
}
|
||||
|
||||
/** 生成报告分享链接(与 H5 ShareReportButton:POST /query/generate_share_link) */
|
||||
export async function postGenerateShareLink(body, requestConfig) {
|
||||
const res = await http.post('/query/generate_share_link', body, requestConfig)
|
||||
return res.data
|
||||
}
|
||||
|
||||
@@ -18,12 +18,23 @@ const maskedName = computed(() => {
|
||||
return name.length > 1 ? `${name[0]}${'*'.repeat(name.length - 1)}` : '*'
|
||||
})
|
||||
|
||||
const status = computed(() => {
|
||||
const s = Number(p.value.status)
|
||||
/** 接口实际为 { result: { status } },示例数据可能为顶层 { status } */
|
||||
function readStatus(payload) {
|
||||
if (!payload || typeof payload !== 'object')
|
||||
return null
|
||||
const direct = Number(payload.status)
|
||||
if ([0, -1, -2, -4].includes(direct))
|
||||
return direct
|
||||
const nested = payload.result
|
||||
if (nested && typeof nested === 'object') {
|
||||
const s = Number(nested.status)
|
||||
if ([0, -1, -2, -4].includes(s))
|
||||
return s
|
||||
}
|
||||
return null
|
||||
})
|
||||
}
|
||||
|
||||
const status = computed(() => readStatus(p.value))
|
||||
|
||||
const resultText = computed(() => {
|
||||
const s = status.value
|
||||
|
||||
@@ -182,6 +182,16 @@
|
||||
"navigationBarTextStyle": "black",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/webview/index",
|
||||
"type": "page",
|
||||
"style": {
|
||||
"navigationBarTitleText": "网页",
|
||||
"navigationStyle": "default",
|
||||
"navigationBarBackgroundColor": "#ffffff",
|
||||
"navigationBarTextStyle": "black"
|
||||
}
|
||||
}
|
||||
],
|
||||
"subPackages": [],
|
||||
|
||||
@@ -35,7 +35,7 @@ function readQueryParams(row: Record<string, unknown>): Record<string, unknown>
|
||||
}
|
||||
|
||||
function pickVin(qp: Record<string, unknown>): string {
|
||||
const keys = ['vin_code', 'vin', 'frame_no', 'VIN', '车架号']
|
||||
const keys = ['vin_code', 'vin', 'frame_no', 'VIN', '车架号', 'plate_no', 'car_license', '车牌号']
|
||||
for (const k of keys) {
|
||||
const v = qp[k]
|
||||
if (typeof v === 'string' && v.trim())
|
||||
@@ -47,7 +47,7 @@ function pickVin(qp: Record<string, unknown>): string {
|
||||
}
|
||||
|
||||
function pickModel(qp: Record<string, unknown>): string {
|
||||
const keys = ['model', 'vehicle_model', 'car_model', '车型', 'name', 'car_name']
|
||||
const keys = ['carplate_type', 'car_type', 'model', 'vehicle_model', 'car_model', '车型', 'car_name']
|
||||
for (const k of keys) {
|
||||
const v = qp[k]
|
||||
if (typeof v === 'string' && v.trim())
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<script setup>
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { ref } from 'vue'
|
||||
import { getQueryDetailByOrderId, getQueryDetailByOrderNo } from '@/api'
|
||||
import { getQueryDetailByOrderId, getQueryDetailByOrderNo, postGenerateShareLink } from '@/api'
|
||||
import VehicleReportShell from '@/components/report/VehicleReportShell.vue'
|
||||
import { buildReportShareUrl } from '@/utils/h5BaseUrl'
|
||||
import { normalizeVehicleQueryData } from '@/utils/vehicleReportNormalize'
|
||||
|
||||
definePage({
|
||||
@@ -21,6 +22,7 @@ const errText = ref('')
|
||||
const productName = ref('')
|
||||
const queryParams = ref({})
|
||||
const rows = ref(normalizeVehicleQueryData([]))
|
||||
const shareLoading = ref(false)
|
||||
|
||||
onLoad((options) => {
|
||||
orderNo.value = options?.orderNo || ''
|
||||
@@ -58,6 +60,65 @@ async function load() {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function openReportInWebview(url, title = '报告详情') {
|
||||
if (!url)
|
||||
return
|
||||
// #ifdef H5
|
||||
if (typeof window !== 'undefined') {
|
||||
window.open(url, '_blank')
|
||||
return
|
||||
}
|
||||
// #endif
|
||||
uni.navigateTo({
|
||||
url: `/pages/webview/index?url=${encodeURIComponent(url)}&title=${encodeURIComponent(title)}`,
|
||||
})
|
||||
}
|
||||
|
||||
function copyShareUrl(url) {
|
||||
uni.setClipboardData({
|
||||
data: url,
|
||||
success: () => uni.showToast({ title: '链接已复制', icon: 'none' }),
|
||||
})
|
||||
}
|
||||
|
||||
async function handleShareReport() {
|
||||
if (shareLoading.value)
|
||||
return
|
||||
if (!orderNo.value && !orderId.value) {
|
||||
uni.showToast({ title: '缺少订单信息', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
shareLoading.value = true
|
||||
try {
|
||||
const body = orderId.value
|
||||
? { order_id: Number.parseInt(orderId.value, 10) }
|
||||
: { order_no: orderNo.value }
|
||||
const res = await postGenerateShareLink(body)
|
||||
if (res?.code !== 200 || !res.data?.share_link) {
|
||||
uni.showToast({ title: res?.msg || '生成分享链接失败', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
const shareUrl = buildReportShareUrl(res.data.share_link)
|
||||
uni.showActionSheet({
|
||||
itemList: ['在网页版查看完整报告', '复制分享链接'],
|
||||
success: (tap) => {
|
||||
if (tap.tapIndex === 0)
|
||||
openReportInWebview(shareUrl)
|
||||
else if (tap.tapIndex === 1)
|
||||
copyShareUrl(shareUrl)
|
||||
},
|
||||
})
|
||||
}
|
||||
catch {
|
||||
uni.showToast({ title: '生成分享链接失败', icon: 'none' })
|
||||
}
|
||||
finally {
|
||||
shareLoading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -75,6 +136,17 @@ async function load() {
|
||||
:query-params="queryParams"
|
||||
:rows="rows"
|
||||
/>
|
||||
<view class="share-bar">
|
||||
<button
|
||||
class="share-btn"
|
||||
:loading="shareLoading"
|
||||
:disabled="shareLoading"
|
||||
@click="handleShareReport"
|
||||
>
|
||||
分享报告
|
||||
</button>
|
||||
<text class="share-tip">完整报告可在网页版查看,避免小程序渲染异常</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -97,4 +169,35 @@ async function load() {
|
||||
padding: 24rpx 24rpx 48rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.share-bar {
|
||||
margin-top: 32rpx;
|
||||
padding: 0 8rpx 16rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.share-btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
border-radius: 44rpx;
|
||||
background: #1768ff;
|
||||
color: #fff;
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.share-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.share-tip {
|
||||
margin-top: 16rpx;
|
||||
font-size: 24rpx;
|
||||
color: #86909c;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
66
src/pages/webview/index.vue
Normal file
66
src/pages/webview/index.vue
Normal file
@@ -0,0 +1,66 @@
|
||||
<script setup>
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { ref } from 'vue'
|
||||
|
||||
definePage({
|
||||
style: {
|
||||
navigationBarTitleText: '网页',
|
||||
navigationStyle: 'default',
|
||||
navigationBarBackgroundColor: '#ffffff',
|
||||
navigationBarTextStyle: 'black',
|
||||
},
|
||||
})
|
||||
|
||||
const pageUrl = ref('')
|
||||
|
||||
onLoad((options) => {
|
||||
pageUrl.value = options?.url ? decodeURIComponent(options.url) : ''
|
||||
const title = options?.title ? decodeURIComponent(options.title) : ''
|
||||
if (title)
|
||||
uni.setNavigationBarTitle({ title })
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="webview-page">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<web-view v-if="pageUrl" :src="pageUrl" />
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<view v-if="pageUrl" class="fallback">
|
||||
<text class="fallback-tip">当前环境不支持内嵌网页,请复制链接到浏览器打开</text>
|
||||
<text class="fallback-url">{{ pageUrl }}</text>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<view v-if="!pageUrl" class="empty">
|
||||
链接无效
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.webview-page {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.empty,
|
||||
.fallback {
|
||||
padding: 100rpx 32rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: #86909c;
|
||||
}
|
||||
|
||||
.fallback-tip {
|
||||
display: block;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.fallback-url {
|
||||
display: block;
|
||||
word-break: break-all;
|
||||
color: #1768ff;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -51,10 +51,13 @@ const maskedName = computed(() => {
|
||||
return name.length > 1 ? name[0] + '*'.repeat(name.length - 1) : '*';
|
||||
});
|
||||
|
||||
// status: 0 一致, -1 不一致, -2 非法姓名, -4 无记录
|
||||
// status: 0 一致, -1 不一致, -2 非法姓名, -4 无记录(接口多为 result.status)
|
||||
const status = computed(() => {
|
||||
const s = props.data?.status;
|
||||
if (s === 0 || s === -1 || s === -2 || s === -4) return s;
|
||||
const d = props.data;
|
||||
const direct = d?.status;
|
||||
if (direct === 0 || direct === -1 || direct === -2 || direct === -4) return direct;
|
||||
const nested = d?.result?.status;
|
||||
if (nested === 0 || nested === -1 || nested === -2 || nested === -4) return nested;
|
||||
return null;
|
||||
});
|
||||
|
||||
|
||||
18
src/utils/h5BaseUrl.js
Normal file
18
src/utils/h5BaseUrl.js
Normal file
@@ -0,0 +1,18 @@
|
||||
/** H5 站点根地址,用于构造报告分享 / 网页版链接 */
|
||||
export function resolveH5BaseUrl() {
|
||||
const fromEnv = import.meta.env.VITE_H5_BASE_URL
|
||||
if (fromEnv)
|
||||
return String(fromEnv).replace(/\/$/, '')
|
||||
|
||||
const apiBase = import.meta.env.VITE_API_BASE_URL || ''
|
||||
if (apiBase.includes('/api/v1'))
|
||||
return apiBase.replace(/\/api\/v1\/?$/, '')
|
||||
|
||||
return 'https://www.tianyuancha.cn'
|
||||
}
|
||||
|
||||
/** 与 tyc-webview-v2 ShareReportButton 一致:/report/share/:linkId */
|
||||
export function buildReportShareUrl(linkId) {
|
||||
const base = resolveH5BaseUrl()
|
||||
return `${base}/report/share/${encodeURIComponent(linkId)}`
|
||||
}
|
||||
3
uni-pages.d.ts
vendored
3
uni-pages.d.ts
vendored
@@ -21,7 +21,8 @@ type _LocationUrl =
|
||||
"/pages/report/detail" |
|
||||
"/pages/toolbox/category" |
|
||||
"/pages/toolbox/index" |
|
||||
"/pages/toolbox/query";
|
||||
"/pages/toolbox/query" |
|
||||
"/pages/webview/index";
|
||||
|
||||
interface NavigateToOptions {
|
||||
url: _LocationUrl;
|
||||
|
||||
Reference in New Issue
Block a user