This commit is contained in:
liangzai 2024-12-28 00:05:20 +08:00
parent 0bf9d95075
commit d7d10f55bc
24 changed files with 1839 additions and 149 deletions

View File

@ -24,3 +24,6 @@ a,
.card {
@apply shadow rounded-xl bg-white p-6;
}
.ltitle {
@apply mx-auto mt-2 w-64 border rounded-3xl bg-gradient-to-r from-blue-400 via-green-500 to-teal-500 py-2 text-center text-white font-bold;
}

File diff suppressed because one or more lines are too long

View File

@ -29,7 +29,7 @@
//
function goBack() {
unionuni.navigateBack({ delta: 1 })
uni.navigateBack({ delta: 1 })
}
</script>

View File

@ -6,7 +6,6 @@ export function useWebView() {
// 检测环境并通知父窗口加载完毕
const handleBridgeReady = (platformName) => {
console.log("handleBridgeReady", platformName)
if (platformName.h5) {
window.parent.postMessage({ loaded: true }, "*");
}
@ -30,7 +29,6 @@ export function useWebView() {
};
onMounted(() => {
console.log(" /MicroMessenger/i.test(navigator.userAgent)", /MicroMessenger/i.test(navigator.userAgent))
// 检测平台环境
uni.getEnv((env) => {
platform.value = env;

102
src/ui/CDualMarriage.vue Normal file
View File

@ -0,0 +1,102 @@
<template>
<div class="flex items-center justify-center card">
<div class="max-w-md w-full p-4">
<!-- 核验双方信息 -->
<h3 class="text-lg font-semibold text-gray-700 mb-2">核验双方信息</h3>
<div class="text-sm text-gray-600 space-y-2 mb-6">
<p>
<span class="font-medium text-gray-800">男方姓名</span>
{{ maskedParams.nameMan }}
</p>
<p>
<span class="font-medium text-gray-800">男方身份证号</span>
{{ maskedParams.idCardMan }}
</p>
<p>
<span class="font-medium text-gray-800">女方姓名</span>
{{ maskedParams.nameWoman }}
</p>
<p>
<span class="font-medium text-gray-800">女方身份证号</span>
{{ maskedParams.idCardWoman }}
</p>
</div>
<!-- 核验结果 -->
<h3 class="text-xl font-semibold text-gray-700 mb-4">婚姻核验结果</h3>
<div
:class="['mb-6 p-2 rounded-3xl text-lg font-medium text-center text-white shadow-lg', getStatusClass(data.status)]">
{{ getStatusText(data.status) }}
</div>
<div class="text-sm text-gray-600">
<p>{{ statusDescription(data.status) }}</p>
</div>
</div>
</div>
</template>
<script setup>
const props = defineProps({
data: {
type: Object,
required: true,
},
params: {
type: Object,
required: true,
},
});
//
const getStatusClass = (status) => {
const statusClassMapping = {
"0": "bg-yellow-500",
"1": "bg-green-600",
"2": "bg-red-500",
"3": "bg-blue-400",
};
return statusClassMapping[status] || "bg-gray-500";
};
//
const getStatusText = (status) => {
const statusMapping = {
"0": "无婚姻关系",
"1": "已婚",
"2": "已离婚",
"3": "离婚冷静期",
};
return statusMapping[status] || "未知状态";
};
const statusDescription = (status) => {
const descriptionMapping = {
"1": "双方是夫妻关系,目前处于已婚状态。",
"2": "双方存在过婚姻关系,目前已离婚。",
"3": "双方目前处于离婚冷静期。",
"0": "双方不存在婚姻关系。",
};
return descriptionMapping[status] || "无详细描述。";
};
//
const maskValue = (value, type) => {
if (type === "name") {
//
return value.length > 1 ? value[0] + "*".repeat(value.length - 1) : "*";
} else if (type === "id_card") {
// 64
return value.replace(/^(.{6})(?:\d+)(.{4})$/, "$1****$2");
}
return value;
};
const maskedParams = {
nameMan: maskValue(props.params.nameMan, "name"),
idCardMan: maskValue(props.params.idCardMan, "id_card"),
nameWoman: maskValue(props.params.nameWoman, "name"),
idCardWoman: maskValue(props.params.idCardWoman, "id_card"),
};
</script>
<style scoped></style>

84
src/ui/CFIN019.vue Normal file
View File

@ -0,0 +1,84 @@
<template>
<div class="p-4 card space-y-4">
<!-- 核验对象信息 -->
<div class="">
<LTitle title="核验对象" type="blue-green" class="mb-4"></LTitle>
<div class="space-y-2">
<div class="flex justify-between">
<span class="font-medium">银行卡号:</span>
<span>{{ maskValue(params.bank_card, 'bank_card') }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium">身份证号:</span>
<span>{{ maskValue(params.id_card, 'id_card') }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium">手机号:</span>
<span>{{ maskValue(params.mobile, 'mobile') }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium">姓名:</span>
<span>{{ maskValue(params.name, 'name') }}</span>
</div>
</div>
</div>
<!-- 黑名单信息 -->
<div class="">
<LTitle title="银行卡黑名单信息" type="blue-green" class="mb-4"></LTitle>
<div class="space-y-4">
<div v-for="(value, key) in data" :key="key" class="flex justify-between items-center">
<div class="font-medium">{{ labelMap[key] }}</div>
<div
:class="['text-white rounded-lg font-bold py-1 px-2', { 'bg-red-500': value === '1', 'bg-green-500': value === '0' }]">
{{ value === '0' ? '未存在' : '被列入该黑名单' }}
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { defineProps } from 'vue'
// props
const props = defineProps({
data: {
type: Object,
required: true,
},
params: {
type: Object,
required: true,
}
})
//
const labelMap = {
onlineBlack: "线上卡号黑名单",
offlineBlack: "线下卡号黑名单",
badCardHolder: "不良持卡人名单",
fraudTrans: "交易欺诈名单",
otherBlack: "其他卡号黑名单",
caseRelated: "涉案卡片"
}
//
const maskValue = (value, type) => {
if (type === "name") {
return value.length > 1 ? value[0] + "*".repeat(value.length - 1) : "*";
} else if (type === "id_card") {
return value.replace(/^(.{6})(?:\d+)(.{4})$/, "$1****$2");
} else if (type === "mobile") {
return value.replace(/^(\d{3})(?:\d+)(\d{4})$/, "$1****$2");
} else if (type === "bank_card") {
return value.replace(/^(\d{4})(?:\d+)(\d{4})$/, "$1****$2");
}
return value;
};
</script>
<style scoped>
/* 添加需要的样式 */
</style>

74
src/ui/CG02BJ02.vue Normal file
View File

@ -0,0 +1,74 @@
<template>
<div class="card">
<div class="pb-4">
<h3 class="text-xl font-semibold mb-4">校验对象</h3>
<ul>
<li class="flex justify-between py-2 border-b">
<span class="font-medium">手机号码</span>
<span>{{ maskMobile(params?.mobile) }}</span>
</li>
</ul>
</div>
<!-- 手机在网时长状态展示 -->
<div class=" bg-blue-100 text-blue-700 p-4 rounded-lg mb-6">
<h3 class="text-xl font-semibold">手机在网时长</h3>
<p class="text-lg font-medium">{{ getTimeDuration(data?.code) }}</p>
<p class="text-sm mt-2">运营商{{ getPhoneType(data?.phoneType) }}</p>
</div>
<!-- 手机号码展示 -->
</div>
</template>
<script setup>
import { defineProps } from 'vue';
// props
const props = defineProps({
data: Object,
params: Object,
});
//
const maskMobile = (mobile) => {
if (!mobile) return '';
return mobile.replace(/^(\d{3})(?:\d+)(\d{4})$/, "$1****$2");
};
// code
const getTimeDuration = (code) => {
switch (code) {
case 1006:
return "0 - 3 个月";
case 1007:
return "3 - 6 个月";
case 1008:
return "6 - 12 个月";
case 1009:
return "12 - 24 个月";
case 1010:
return "24 个月以上";
default:
return "未知时长";
}
};
// phoneType
const getPhoneType = (phoneType) => {
switch (phoneType) {
case "CMCC":
return "中国移动";
case "CUCC":
return "中国联通";
case "CTCC":
return "中国电信";
default:
return "未知运营商";
}
};
</script>
<style scoped>
/* 自定义样式 */
</style>

61
src/ui/CG03HZ01.vue Normal file
View File

@ -0,0 +1,61 @@
<template>
<div class="card">
<!-- 手机号码展示 -->
<div class="mb-4">
<h3 class="text-xl font-semibold mb-4">校验对象</h3>
<ul>
<li class="flex justify-between py-2">
<span class="font-medium">手机号码</span>
<span>{{ maskMobile(params?.mobile) }}</span>
</li>
</ul>
</div>
<!-- 风险等级展示 -->
<div v-if="data?.filterType === '0'" class="bg-green-100 text-green-700 p-4 rounded-lg mb-6">
<h3 class="text-xl font-semibold">安全号码</h3>
<p class="text-sm">该手机号码为安全号码没有发现任何风险</p>
</div>
<div v-if="data?.filterType === '1'" class="bg-red-100 text-red-700 p-4 rounded-lg mb-6">
<h3 class="text-xl font-semibold">高危</h3>
<p class="text-sm">该手机号码存在较高风险请谨慎处理</p>
</div>
<div v-if="data?.filterType === '2'" class="bg-yellow-100 text-yellow-700 p-4 rounded-lg mb-6">
<h3 class="text-xl font-semibold">中危</h3>
<p class="text-sm">该手机号码存在一定风险请留意相关信息</p>
</div>
<div v-if="data?.filterType === '3'" class="bg-blue-100 text-blue-700 p-4 rounded-lg mb-6">
<h3 class="text-xl font-semibold">低危</h3>
<p class="text-sm">该手机号码风险较低但仍需关注</p>
</div>
</div>
</template>
<script setup>
import { defineProps } from 'vue';
// props
const props = defineProps({
data: {
type: Object,
required: true,
},
params: {
type: Object,
required: true,
}
});
//
const maskMobile = (mobile) => {
if (!mobile) return '';
return mobile.replace(/^(\d{3})(?:\d+)(\d{4})$/, "$1****$2");
};
</script>
<style scoped>
/* 自定义样式 */
</style>

61
src/ui/CG19BJ02.vue Normal file
View File

@ -0,0 +1,61 @@
<template>
<div class="card">
<!-- 手机号码展示 -->
<div class="pb-4">
<h3 class="text-xl font-semibold mb-4">校验对象</h3>
<ul>
<li class="flex justify-between py-2 border-b">
<span class="font-medium">手机号码</span>
<span>{{ maskMobile(params?.mobile) }}</span>
</li>
<li class="flex justify-between py-2 border-b">
<span class="font-medium">业务日期</span>
<span>{{ formatDate(params?.startDate) }}</span>
</li>
</ul>
</div>
<!-- 二次卡状态展示 -->
<div v-if="data?.code === 1026" class="bg-green-100 text-gray-700 p-4 rounded-lg mb-6">
<h3 class="text-xl font-semibold">非二次卡</h3>
<p class="text-sm">该手机号码不是二次卡请注意核对</p>
</div>
<div v-if="data?.code === 1025" class="bg-red-500 text-white p-4 rounded-lg mb-6">
<h3 class="text-xl font-semibold">二次卡</h3>
<p class="text-sm">该手机号码是二次卡请注意核对</p>
</div>
</div>
</template>
<script setup>
import { defineProps } from 'vue';
// props
const props = defineProps({
data: Object,
params: Object,
});
props.data.code = 1025
//
const maskMobile = (mobile) => {
if (!mobile) return '';
return mobile.replace(/^(\d{3})(?:\d+)(\d{4})$/, "$1****$2");
};
// YYYY-MM-DD
const formatDate = (dateString) => {
if (!dateString) return '';
// 8 YYYYMMDD
const year = dateString.slice(0, 4);
const month = dateString.slice(4, 6);
const day = dateString.slice(6, 8);
//
return `${year}-${month}-${day}`;
};
</script>
<style scoped>
/* 自定义样式 */
</style>

123
src/ui/CG20GZ01.vue Normal file
View File

@ -0,0 +1,123 @@
<template>
<div class="card">
<!-- 校验对象展示 -->
<div class="">
<h3 class="text-lg font-medium mb-3">校验对象</h3>
<ul>
<li class="flex justify-between py-2 border-b">
<span class="font-medium">姓名</span>
<span>{{ maskValue(params?.name, 'name') }}</span>
</li>
<li class="flex justify-between py-2 border-b">
<span class="font-medium">身份证号</span>
<span>{{ maskValue(params?.id_card, 'id_card') }}</span>
</li>
<li class="flex justify-between py-2 border-b">
<span class="font-medium">手机号码</span>
<span>{{ maskValue(params?.mobile, 'mobile') }}</span>
</li>
<li class="flex justify-between py-2">
<span class="font-medium">银行卡号</span>
<span>{{ maskValue(params?.bank_card, 'bank_card') }}</span>
</li>
</ul>
</div>
<!-- 状态展示 -->
<div :class="stateClass" class="text-center mt-6 rounded-lg py-2">
<h2 class="text-xl font-semibold mb-2">银行卡四要素校验</h2>
<p class="text-sm">{{ stateMessage }}</p>
</div>
</div>
</template>
<script setup>
import { defineProps, computed } from 'vue'
// props
const props = defineProps({
data: {
type: Object,
required: true,
},
params: {
type: Object,
required: true,
}
})
//
const stateMessage = computed(() => {
const state = props.data.data.state
switch (state) {
case '1':
return '验证一致';
case '2':
return '验证不一致';
case '3':
return '异常情况';
default:
return '未知状态';
}
})
const stateClass = computed(() => {
const state = props.data.data.state
switch (state) {
case '1':
return 'bg-green-100 text-green-600';
case '2':
return 'bg-red-100 text-red-600';
case '3':
return 'bg-yellow-100 text-yellow-600';
default:
return 'bg-gray-100 text-gray-600';
}
})
//
const maskValue = (value, type) => {
if (!value) return ''; //
if (type === "name") {
//
return value.length > 1 ? value[0] + "*".repeat(value.length - 1) : "*";
} else if (type === "id_card") {
// 64
return value.replace(/^(.{6})(?:\d+)(.{4})$/, "$1****$2");
} else if (type === "mobile") {
//
return value.replace(/^(\d{3})(?:\d+)(\d{4})$/, "$1****$2");
} else if (type === "bank_card") {
//
return value.replace(/^(\d{4})(?:\d+)(\d{4})$/, "$1 **** **** $2");
}
return value; //
};
</script>
<style scoped>
/* 使按钮和状态信息的显示更为美观 */
.bg-green-100 {
background-color: #d1fad6;
}
.bg-red-100 {
background-color: #fcd0d0;
}
.bg-yellow-100 {
background-color: #fdf2b8;
}
.text-green-600 {
color: #16a34a;
}
.text-red-600 {
color: #dc2626;
}
.text-yellow-600 {
color: #e4b200;
}
</style>

View File

@ -0,0 +1,99 @@
<template>
<div class="flex items-center justify-center card">
<div class="max-w-md w-full p-4">
<!-- 请求参数 -->
<h3 class="text-lg font-semibold text-gray-700 mb-2">核验对象</h3>
<div class="text-sm text-gray-600 space-y-2 mb-6">
<p>
<span class="font-medium text-gray-800">姓名</span>
{{ maskedParams.name }}
</p>
<p>
<span class="font-medium text-gray-800">身份证号</span>
{{ maskedParams.id_card }}
</p>
</div>
<!-- 核验结果 -->
<h3 class="text-xl font-semibold text-gray-700 mb-2">二要素验证结果</h3>
<div v-if="data.result === 0" class="flex items-center space-x-4 mb-6">
<div class="h-12 w-12 rounded-full flex flex-shrink-0 items-center justify-center bg-green-500">
<span class="text-white text-lg font-bold"></span>
</div>
<div>
<p class="text-lg font-medium text-gray-800">一致</p>
<p class="text-sm text-gray-500">姓名和身份证号匹配成功</p>
</div>
</div>
<div v-else class="flex items-center space-x-4 mb-6">
<div class="h-12 w-12 rounded-full flex items-center justify-center bg-red-500">
<span class="text-white text-lg font-bold"></span>
</div>
<div>
<p class="text-lg font-medium text-gray-800">不一致</p>
<p class="text-sm text-gray-500">姓名和身份证号不匹配</p>
</div>
</div>
<!-- 核验详情 -->
<h3 class="text-lg font-semibold text-gray-700 mb-2">附加信息</h3>
<div class="text-sm text-gray-600 space-y-2 ">
<p>
<span class="font-medium text-gray-800">地址</span>
{{ data.address }}
</p>
<p>
<span class="font-medium text-gray-800">生日</span>
{{ formatBirthday(data.birthday) }}
</p>
<p>
<span class="font-medium text-gray-800">性别</span>
{{ data.sex }}
</p>
</div>
</div>
</div>
</template>
<script setup>
const props = defineProps({
data: {
type: Object,
required: true,
},
params: {
type: Object,
required: true,
},
});
//
const formatBirthday = (birthday) => {
if (!birthday) return "未知";
const year = birthday.slice(0, 4);
const month = birthday.slice(4, 6);
const day = birthday.slice(6, 8);
return `${year}${month}${day}`;
};
//
const maskValue = (value, type) => {
if (type === "name") {
//
return value.length > 1 ? value[0] + "*".repeat(value.length - 1) : "*";
} else if (type === "id_card") {
// 64
return value.replace(/^(.{6})(?:\d+)(.{4})$/, "$1****$2");
}
return value;
};
const maskedParams = {
name: maskValue(props.params.name, "name"),
id_card: maskValue(props.params.id_card, "id_card"),
};
</script>
<style scoped></style>

240
src/ui/CP_C_B332.vue Normal file
View File

@ -0,0 +1,240 @@
<template>
<div class="flex flex-col items-center card">
<div class="max-w-4xl w-full space-y-6">
<!-- 核验目标 -->
<div>
<LTitle title="核验对象" type="blue-green" class="mb-4"></LTitle>
<div class="text-sm text-gray-600 space-y-2">
<p>
<span class="font-medium text-gray-800">车牌号</span>
{{ params.car_license }}
</p>
<p>
<span class="font-medium text-gray-800">号牌种类</span>
{{ plateTypeMapping[params.car_type] }}
</p>
<p>
<span class="font-medium text-gray-800">车主姓名</span>
{{ maskedParams.name }}
</p>
</div>
</div>
<!-- 基本信息 -->
<div>
<LTitle title="基本信息" type="blue-green" class="mb-4"></LTitle>
<div class="grid grid-cols-1 gap-4">
<div class="flex justify-between">
<span class="font-medium text-gray-800">号牌种类:</span>
<span>{{ plateTypeMapping[data.plateType] }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">核定载客数:</span>
<span>{{ data.passengers }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">车牌号:</span>
<span>{{ data.plate }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">车架号:</span>
<span>{{ data.vin }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">使用性质:</span>
<span>{{ data.properties }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">车辆类型:</span>
<span>{{ data.vehicleType }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">品牌名称:</span>
<span>{{ data.brandName }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">车身颜色:</span>
<span>{{ filterDataNull(bodyColorMapping[data.bodyColor]) }}</span>
</div>
</div>
</div>
<!-- 一致性核验 -->
<div>
<LTitle title="一致性核验" type="blue-green" class="mb-4"></LTitle>
<div class="grid grid-cols-1 gap-4">
<div class="flex justify-between">
<span class="font-medium text-gray-800">车牌种类一致性:</span>
<span>{{ data.carType }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">车牌号一致性:</span>
<span>{{ data.carNumber }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">姓名一致性:</span>
<span>{{ data.name }}</span>
</div>
</div>
</div>
<!-- 发动机信息 -->
<div>
<LTitle title="发动机信息" type="blue-green" class="mb-4"></LTitle>
<div class="grid grid-cols-1 gap-4">
<div class="flex justify-between">
<span class="font-medium text-gray-800">发动机型号:</span>
<span>{{ data.engineModel }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">发动机号:</span>
<span>{{ data.engineNumber }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">排量:</span>
<span>{{ data.cc }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">燃料种类:</span>
<span>{{ data.fuelType }}</span>
</div>
</div>
</div>
<!-- 车辆状态 -->
<div>
<LTitle title="车辆状态" type="blue-green" class="mb-4"></LTitle>
<div class="grid grid-cols-1 gap-4">
<div class="flex justify-between">
<span class="font-medium text-gray-800">机动车状态:</span>
<span>{{ data.vehicleStatus }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">强制报废期止:</span>
<span>{{ filterDataNull(data.retirementDate) }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">检验有效期止:</span>
<span>{{ filterDataNull(data.validityDayEnd) }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">初次登记日期:</span>
<span>{{ filterDataNull(data.firstIssueDate) }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">年检日期:</span>
<span>{{ filterDataNull(data.jianCheTime) }}</span>
</div>
</div>
</div>
<!-- 尺寸及重量 -->
<div>
<LTitle title="车辆尺寸及重量" type="blue-green" class="mb-4"></LTitle>
<div class="grid grid-cols-1 gap-4">
<div class="flex justify-between">
<span class="font-medium text-gray-800">总质量:</span>
<span>{{ filterDataNull(data.crossWeight) }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">整备质量:</span>
<span>{{ filterDataNull(data.curbWeight) }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">轴数:</span>
<span>{{ filterDataNull(data.shaft) }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">轴距:</span>
<span>{{ filterDataNull(data.wheelBase) }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">前轮距:</span>
<span>{{ filterDataNull(data.frontTread) }}</span>
</div>
<div class="flex justify-between">
<span class="font-medium text-gray-800">后轮距:</span>
<span>{{ filterDataNull(data.rearTread) }}</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
const props = defineProps({
data: {
type: Object,
required: true,
},
params: {
type: Object,
required: true,
},
});
//
const plateTypeMapping = {
"02": "小型汽车",
"01": "大型汽车",
"03": "使馆汽车",
"04": "领馆汽车",
"05": "境外汽车",
"06": "外籍汽车",
"07": "普通摩托车",
"08": "轻便摩托车",
"09": "使馆摩托车",
"10": "领馆摩托车",
"11": "境外摩托车",
"12": "外籍摩托车",
"13": "低速车",
"14": "拖拉机",
"15": "挂车",
"16": "教练汽车",
"17": "教练摩托车",
"20": "临时入境汽车",
"21": "临时入境摩托车",
"22": "临时行驶车",
"23": "警用汽车",
"24": "警用摩托",
"51": "新能源大型汽车",
"52": "新能源小型汽车"
};
//
const bodyColorMapping = {
"A": "白",
"B": "灰",
"C": "黄",
"D": "粉",
"E": "红",
"F": "紫",
"G": "绿",
"H": "蓝",
"I": "棕",
"J": "黑",
"K": "香槟",
"L": "银",
"M": "橙",
"N": "金",
"Z": "其他"
};
//
const maskValue = (value, type) => {
if (type === "name") {
return value.length > 1 ? value[0] + "*".repeat(value.length - 1) : "*";
}
return value;
};
const filterDataNull = (data) => {
return data ? data : '-'
}
const maskedParams = {
name: maskValue(props.params.name, "name"),
};
</script>
<style scoped></style>

View File

@ -0,0 +1,105 @@
<template>
<div class="flex items-center justify-center card">
<div class="max-w-md w-full p-2">
<h3 class="text-lg font-semibold text-gray-700 mb-2">核验对象</h3>
<div class="text-sm text-gray-600 space-y-2 mb-8">
<p>
<span class="font-medium text-gray-800">姓名</span>
{{ maskedParams.name }}
</p>
<p>
<span class="font-medium text-gray-800">身份证号</span>
{{ maskedParams.id_card }}
</p>
<p>
<span class="font-medium text-gray-800">手机号</span>
{{ maskedParams.mobile }}
</p>
</div>
<van-divider />
<!-- 核验结果 -->
<h3 class="text-xl font-semibold text-gray-700 mb-2">核验结果</h3>
<div v-if="result" class="flex items-center space-x-4 mb-8">
<div
:class="['h-12 w-12 rounded-full flex flex-shrink-0 items-center justify-center', result.statusClass]">
<span class="text-white text-lg font-bold">{{ result.icon }}</span>
</div>
<div>
<p class="text-lg font-medium text-gray-800">{{ result.message }}</p>
<p class="text-sm text-gray-500">{{ result.description }}</p>
</div>
</div>
<div v-else class="text-center mb-6">
<p class="text-gray-500">无效的核验代码</p>
</div>
<!-- 三要素请求参数 -->
</div>
</div>
</template>
<script setup>
const props = defineProps({
data: {
type: Object,
required: true,
},
params: {
type: Object,
required: true,
},
});
//
const codeMapping = {
1000: {
statusClass: "bg-green-500",
icon: "✔",
message: "一致",
description: "姓名、证件号与手机号码信息完全匹配。",
},
1003: {
statusClass: "bg-yellow-500",
icon: "⚠",
message: "不一致",
description: "姓名、证件号与手机号码信息不一致。",
},
1004: {
statusClass: "bg-red-500",
icon: "✘",
message: "姓名不正确",
description: "请检查姓名输入是否正确。",
},
1005: {
statusClass: "bg-red-500",
icon: "✘",
message: "证件号码不正确",
description: "请检查证件号码输入是否正确。",
},
};
const result = codeMapping[props.data.code];
//
const maskValue = (value, type) => {
if (type === "name") {
//
return value.length > 1 ? value[0] + "*".repeat(value.length - 1) : "*";
} else if (type === "id_card") {
// 64
return value.replace(/^(.{6})(?:\d+)(.{4})$/, "$1****$2");
} else if (type === "mobile") {
//
return value.replace(/^(\d{3})(?:\d+)(\d{4})$/, "$1****$2");
}
return value;
};
const maskedParams = {
name: maskValue(props.params.name, "name"),
id_card: maskValue(props.params.id_card, "id_card"),
mobile: maskValue(props.params.mobile, "mobile"),
};
</script>
<style scoped></style>

View File

@ -0,0 +1,91 @@
<template>
<div class="flex items-center justify-center card">
<div class="max-w-md w-full p-4">
<!-- 请求参数 -->
<h3 class="text-lg font-semibold text-gray-700 mb-2">核验对象</h3>
<div class="text-sm text-gray-600 space-y-2 mb-6">
<p>
<span class="font-medium text-gray-800">姓名</span>
{{ maskedParams.name }}
</p>
<p>
<span class="font-medium text-gray-800">手机号</span>
{{ maskedParams.mobile }}
</p>
</div>
<!-- 核验结果 -->
<h3 class="text-xl font-semibold text-gray-700 mb-4">手机二要素验证结果</h3>
<div v-if="data.code === '1000'" class="flex items-center space-x-4 mb-6">
<div class="h-12 w-12 rounded-full flex flex-shrink-0 items-center justify-center bg-green-500">
<span class="text-white text-lg font-bold"></span>
</div>
<div>
<p class="text-lg font-medium text-gray-800">一致</p>
<p class="text-sm text-gray-500">姓名和手机号匹配成功</p>
</div>
</div>
<div v-else class="flex items-center space-x-4 mb-6">
<div class="h-12 w-12 rounded-full flex items-center flex-shrink-0 justify-center bg-red-500">
<span class="text-white text-lg font-bold"></span>
</div>
<div>
<p class="text-lg font-medium text-gray-800">不一致</p>
<p class="text-sm text-gray-500">手机二要素验证失败请检查输入信息</p>
</div>
</div>
<!-- 核验详情 -->
<h3 class="text-lg font-semibold text-gray-700 mb-2">附加信息</h3>
<div class="text-sm text-gray-600 space-y-2">
<p>
<span class="font-medium text-gray-800">运营商类型</span>
{{ getPhoneType(data.data.phoneType) }}
</p>
</div>
</div>
</div>
</template>
<script setup>
const props = defineProps({
data: {
type: Object,
required: true,
},
params: {
type: Object,
required: true,
},
});
//
const getPhoneType = (type) => {
const phoneTypeMapping = {
CMCC: "中国移动",
CUCC: "中国联通",
CTCC: "中国电信",
};
return phoneTypeMapping[type] || "未知类型";
};
//
const maskValue = (value, type) => {
if (type === "name") {
//
return value.length > 1 ? value[0] + "*".repeat(value.length - 1) : "*";
} else if (type === "mobile") {
//
return value.replace(/^(\d{3})(?:\d+)(\d{4})$/, "$1****$2");
}
return value;
};
const maskedParams = {
name: maskValue(props.params.name, "name"),
mobile: maskValue(props.params.mobile, "mobile"),
};
</script>
<style scoped></style>

View File

@ -4,16 +4,11 @@
<div class="text-center text-2xl font-bold mb-4">授权书</div>
<!-- 授权书滚动区域 -->
<div
class="authrization-card card flex-1 overflow-y-auto"
ref="agreementBox"
@scroll="handleScroll"
>
<div class="authrization-card card flex-1 overflow-y-auto" ref="agreementBox" @scroll="handleScroll">
<p class="my-2">海南省学宇思网络科技有限公司</p>
<p class="indent-[2em]">
本人<span class="font-bold">
{{ signature ? userData.name : "____________" }}</span
>
{{ signature ? userData.name : "____________" }}</span>
拟向贵司申请大数据分析报告查询业务贵司需要了解本人相关状况用于查询大数据分析报告因此本人同意向贵司提供本人的姓名和手机号等个人信息并同意贵司向第三方包括但不限于西部数据交易有限公司传送上述信息第三方将使用上述信息核实信息真实情况查询信用记录并生成报告
</p>
<p class="mt-2 font-bold">授权内容如下</p>
@ -69,7 +64,7 @@
本人有权随时撤回本授权书中的授权但撤回前的授权行为及其法律后果仍具有法律效力若需撤回授权本人可通过贵司官方渠道提交书面申请贵司将在收到申请后依法停止对本人数据的使用
</li>
<li>
你通过全能查APP或推广方推广查询模式自愿支付相应费用用于购买海南省学宇思网络科技有限公司的大数据报告产品如若对产品内容存在异议可通过邮箱admin@iieeii.com或APP联系客服按钮进行反馈贵司将在收到异议之日起20日内进行核查和处理并将结果答复
你通过全能查或推广方推广查询模式自愿支付相应费用用于购买海南省学宇思网络科技有限公司的大数据报告产品如若对产品内容存在异议可通过邮箱admin@iieeii.com或APP联系客服按钮进行反馈贵司将在收到异议之日起20日内进行核查和处理并将结果答复
</li>
<li>
你向海南省学宇思网络科技有限公司的支付方式为海南省学宇思网络科技有限公司及其经官方授权的相关企业的支付宝账户
@ -91,7 +86,7 @@
<p class="mt-4 font-bold">
签署人<span class="underline">{{
signature ? userData.name : "____________"
}}</span>
}}</span>
<br />
手机号码<span class="underline">
{{ signature ? userData.phone : "____________" }}
@ -102,24 +97,15 @@
</div>
<!-- 操作按钮 -->
<div class="mt-4 flex justify-between">
<button
class="flex-shrink-0 bg-red-500 text-white px-4 py-2 rounded-lg"
@click="cancel"
>
<button class="flex-shrink-0 bg-red-500 text-white px-4 py-2 rounded-lg" @click="cancel">
取消
</button>
<div class="mt-2 px-2 text-center text-sm text-gray-500">
{{ scrollMessage }}
</div>
<button
class="flex-shrink-0 bg-blue-500 text-white px-4 py-2 rounded-lg active:bg-blue-600"
:class="
!canAgree &&
'bg-gray-300 cursor-not-allowed active:bg-gray-300'
"
:disabled="!canAgree"
@click="agree"
>
<button class="flex-shrink-0 bg-blue-500 text-white px-4 py-2 rounded-lg active:bg-blue-600" :class="!canAgree &&
'bg-gray-300 cursor-not-allowed active:bg-gray-300'
" :disabled="!canAgree" @click="agree">
{{ signature ? "同意" : "签署" }}
</button>
</div>

View File

@ -7,6 +7,8 @@
</template>
<script setup>
import { useWebView } from "@/composables/useWebView";
useWebView()
onMounted(() => {
//
(function (d, t) {

View File

@ -1,21 +1,35 @@
<script setup>
import { ref, reactive, computed, onMounted, onUnmounted } from "vue";
import { aesEncrypt } from '@/utils/crypto'
import { aesEncrypt } from "@/utils/crypto";
import { useRoute } from "vue-router";
import { useWebView } from "@/composables/useWebView";
import Authorization from "@/components/Authorization.vue";
import Payment from "@/components/Payment.vue";
import CarNumberInput from "@/components/CarNumberInput.vue";
const route = useRoute();
useWebView()
useWebView();
const showAuthorizationPopup = ref(false)
const authorization = ref(false)
const showPayment = ref(false)
const queryId = ref(null)
const showAuthorizationPopup = ref(false);
const authorization = ref(false);
const showPayment = ref(false);
const queryId = ref(null);
const name = ref("");
const nameMan = ref("");
const nameWoman = ref("");
const idCard = ref("");
const idCardMan = ref("");
const idCardWoman = ref("");
const mobile = ref("");
const bankCard = ref("");
const startDate = ref([])
const dateVal = ref("")
const showDatePicker = ref(false)
//
const today = new Date();
const maxDate = today; //
// 200011
const minDate = new Date('2000-01-01');
const entName = ref("");
const entCode = ref("");
const verificationCode = ref("");
@ -24,10 +38,71 @@ const isCountingDown = ref(false);
const countdown = ref(60);
const feature = ref(route.params.feature);
const featureData = ref({});
const carLicense = ref("");
const carType = ref("小型汽车");
const carPickerVal = ref([{ value: "02", text: "小型汽车" }]);
const showCarTypePicker = ref(false);
const carTypeColumns = [
{ value: "01", text: "大型汽车" },
{ value: "02", text: "小型汽车" },
{ value: "03", text: "使馆汽车" },
{ value: "04", text: "领馆汽车" },
{ value: "05", text: "境外汽车" },
{ value: "06", text: "外籍汽车" },
{ value: "07", text: "普通摩托车" },
{ value: "08", text: "轻便摩托车" },
{ value: "09", text: "使馆摩托车" },
{ value: "10", text: "领馆摩托车" },
{ value: "11", text: "境外摩托车" },
{ value: "12", text: "外籍摩托车" },
{ value: "13", text: "低速车" },
{ value: "14", text: "拖拉机" },
{ value: "15", text: "挂车" },
{ value: "16", text: "教练汽车" },
{ value: "17", text: "教练摩托车" },
{ value: "20", text: "临时入境汽车" },
{ value: "21", text: "临时入境摩托车" },
{ value: "22", text: "临时行驶车" },
{ value: "23", text: "警用汽车" },
{ value: "24", text: "警用摩托车" },
{ value: "51", text: "新能源大型车" },
{ value: "52", text: "新能源小型车" },
];
const formatterDate = (type, option) => {
if (type === 'year') {
option.text += '年';
}
if (type === 'month') {
option.text += '月';
}
if (type === 'day') {
option.text += '日';
}
return option;
};
const onConfirmDate = ({ selectedValues, selectedOptions }) => {
console.log("selectedValues", selectedValues)
console.log("startDate", startDate.value)
dateVal.value = selectedOptions.map(item => item.text).join('');
showDatePicker.value = false
}
const carLicenseChange = (e) => {
console.log("carLicenseChange", e);
carLicense.value = e;
};
const onConfirmCarType = ({ selectedValues, selectedOptions }) => {
console.log(
"selectedValues, selectedOptions",
selectedValues,
selectedOptions
);
showCarTypePicker.value = false;
carPickerVal.value = selectedValues;
carType.value = selectedOptions[0].text;
};
onMounted(() => {
getProduct()
initAuthorization()
getProduct();
initAuthorization();
});
async function getProduct() {
const { data, error } = await useApiFetch(`/product/en/${feature.value}`)
@ -40,15 +115,45 @@ async function getProduct() {
}
function initAuthorization() {
if (noAuthorization.includes(feature.value)) {
authorization.value = true
authorization.value = true;
}
}
const isPhoneNumberValid = computed(() => {
return /^1[3-9]\d{9}$/.test(mobile.value);
});
const isIdCardValid = computed(() => /^\d{17}[\dX]$/i.test(idCard.value));
const isIdCardManValid = computed(() => /^\d{17}[\dX]$/i.test(idCardMan.value));
const isIdCardWomanValid = computed(() =>
/^\d{17}[\dX]$/i.test(idCardWoman.value)
);
const isCreditCodeValid = computed(() => /^.{18}$/.test(entCode.value));
const isCarLicense = computed(() => carLicense.value.trim().length > 6);
const isBankCardValid = computed(() => {
const card = bankCard.value.replace(/\D/g, ""); //
if (card.length < 13 || card.length > 19) {
return false; //
}
let sum = 0;
let shouldDouble = false;
//
for (let i = card.length - 1; i >= 0; i--) {
let digit = parseInt(card.charAt(i));
if (shouldDouble) {
digit *= 2;
if (digit > 9) {
digit -= 9;
}
}
sum += digit;
shouldDouble = !shouldDouble; // 2
}
return sum % 10 === 0; // 10
});
function handleSubmit() {
if (!agreeToTerms.value) {
@ -56,16 +161,80 @@ function handleSubmit() {
return;
}
if (
!validateField('name', name.value, v => v, '请输入姓名') ||
!validateField('mobile', mobile.value, v => isPhoneNumberValid.value, '请输入有效的手机号') ||
!validateField('idCard', idCard.value, v => isIdCardValid.value, '请输入有效的身份证号码') ||
!validateField('verificationCode', verificationCode.value, v => v, '请输入验证码') ||
!validateField('entName', entName.value, v => v, '请输入企业名称') ||
!validateField('entCode', entCode.value, v => isCreditCodeValid.value, '请输入统一社会信用代码')
!validateField("name", name.value, (v) => v, "请输入姓名") ||
!validateField("nameMan", nameMan.value, (v) => v, "请输入男方姓名") ||
!validateField(
"nameWoman",
nameWoman.value,
(v) => v,
"请输入女方姓名"
) ||
!validateField(
"mobile",
mobile.value,
(v) => isPhoneNumberValid.value,
"请输入有效的手机号"
) ||
!validateField(
"idCard",
idCard.value,
(v) => isIdCardValid.value,
"请输入有效的身份证号码"
) ||
!validateField(
"idCardMan",
idCardMan.value,
(v) => isIdCardManValid.value,
"请输入有效的男方身份证号码"
) ||
!validateField(
"idCardWoman",
idCardWoman.value,
(v) => isIdCardWomanValid.value,
"请输入有效的女方身份证号码"
) ||
!validateField(
"bankCard",
bankCard.value,
(v) => isBankCardValid.value,
"请输入有效的银行卡号码"
) ||
!validateField(
"verificationCode",
verificationCode.value,
(v) => v,
"请输入验证码"
) ||
!validateField(
"carPickerVal",
carPickerVal.value,
(v) => v,
"请选择车辆类型"
) ||
!validateField(
"carLicense",
carLicense.value,
(v) => isCarLicense.value,
"请输入正确的车牌号"
) ||
!validateField("entName", entName.value, (v) => v, "请输入企业名称") ||
!validateField(
"entCode",
entCode.value,
(v) => isCreditCodeValid.value,
"请输入统一社会信用代码"
) ||
!validateField(
"date",
dateVal.value,
(v) => v,
"请选择日期"
)
) {
return;
}
submitRequest()
submitRequest();
}
const validateField = (field, value, validationFn, errorMessage) => {
if (isHasInput(field) && !validationFn(value)) {
@ -73,59 +242,108 @@ const validateField = (field, value, validationFn, errorMessage) => {
return false;
}
return true;
}
};
const defaultInput = ["name", "mobile", "idCard", "verificationCode"]
const defaultInput = ["name", "idCard", "mobile", "verificationCode"];
const specialProduct = {
"toc_EnterpriseLawsuit": ["entName", "entCode", "mobile", "verificationCode"]
}
const noAuthorization = ["toc_EnterpriseLawsuit"]
toc_EnterpriseLawsuit: ["entName", "entCode", "mobile", "verificationCode"],
toc_PhoneThreeElements: ["name", "idCard", "mobile"],
toc_IDCardTwoElements: ["name", "idCard"],
toc_PhoneTwoElements: ["name", "mobile"],
toc_PersonVehicleVerification: ["name", "carType", "carLicense"],
toc_VehiclesUnderName: ["name", "idCard"],
toc_DualMarriage: ["nameMan", "idCardMan", "nameWoman", "idCardWoman"],
toc_BankCardBlacklist: ["name", "idCard", "mobile", "bankCard"],
toc_BankCardFourElements: ["name", "idCard", "mobile", "bankCard"],
toc_NaturalLifeStatus: ["name", "idCard"],
toc_NetworkDuration: ["mobile"],
toc_PhoneSecondaryCard: ["mobile", "date"],
toc_PhoneNumberRisk: ["mobile"],
};
const noAuthorization = [
"toc_EnterpriseLawsuit",
"toc_PhoneThreeElements",
"toc_IDCardTwoElements",
"toc_PhoneTwoElements",
"toc_PersonVehicleVerification",
"toc_VehiclesUnderName",
"toc_DualMarriage",
"toc_BankCardBlacklist",
"toc_NaturalLifeStatus",
"toc_NetworkDuration",
"toc_PhoneSecondaryCard",
"toc_PhoneNumberRisk",
"toc_BankCardFourElements",
];
const isHasInput = (input) => {
if (specialProduct[feature.value]) {
return specialProduct[feature.value].includes(input)
return specialProduct[feature.value].includes(input);
} else {
return defaultInput.includes(input)
return defaultInput.includes(input);
}
}
};
async function submitRequest() {
const req = {}
if (isHasInput('name')) {
req.name = name.value
const req = {};
if (isHasInput("name")) {
req.name = name.value;
}
if (isHasInput('id_card')) {
req.id_card = idCard.value
if (isHasInput("idCard")) {
req.id_card = idCard.value;
}
if (isHasInput('mobile')) {
req.mobile = mobile.value
if (isHasInput("nameMan")) {
req.name_man = nameMan.value;
}
if (isHasInput('verificationCode')) {
req.code = verificationCode.value
if (isHasInput("idCardMan")) {
req.id_card_man = idCardMan.value;
}
if (isHasInput('entName')) {
req.ent_name = entName.value
if (isHasInput("nameWoman")) {
req.name_woman = nameWoman.value;
}
if (isHasInput('entCode')) {
req.ent_code = entCode.value
if (isHasInput("idCardWoman")) {
req.id_card_woman = idCardWoman.value;
}
const reqStr = JSON.stringify(req)
const encodeData = aesEncrypt(reqStr, 'ff83609b2b24fc73196aac3d3dfb874f')
if (isHasInput("bankCard")) {
req.bank_card = bankCard.value.replace(/\D/g, "");
}
if (isHasInput("mobile")) {
req.mobile = mobile.value;
}
if (isHasInput("verificationCode")) {
req.code = verificationCode.value;
}
if (isHasInput("carType")) {
req.car_type = carPickerVal.value[0].value;
}
if (isHasInput("carLicense")) {
req.car_license = carLicense.value.trim();
}
if (isHasInput("date")) {
req.start_date = startDate.value.map(item => item).join('')
}
if (isHasInput("entName")) {
req.ent_name = entName.value;
}
if (isHasInput("entCode")) {
req.ent_code = entCode.value;
}
console.log("req", req);
const reqStr = JSON.stringify(req);
const encodeData = aesEncrypt(reqStr, "ff83609b2b24fc73196aac3d3dfb874f");
const { data, error } = await useApiFetch(`/query/service/${feature.value}`)
.post({ data: encodeData })
.json();
if (data.value.code === 200) {
queryId.value = data.value.data.id
queryId.value = data.value.data.id;
if (authorization.value) {
showPayment.value = true
showPayment.value = true;
} else {
showAuthorizationPopup.value = true
showAuthorizationPopup.value = true;
}
}
}
async function sendVerificationCode() {
if (isCountingDown.value || !isPhoneNumberValid.value)
return
if (isCountingDown.value || !isPhoneNumberValid.value) return;
if (!isPhoneNumberValid.value) {
showToast({ message: "请输入有效的手机号" });
return;
@ -158,29 +376,29 @@ function startCountdown() {
}
function toUserAgreement() {
uni.navigateTo({
url: '/pages/userAgreement'
})
url: "/pages/userAgreement",
});
}
function toPrivacyPolicy() {
uni.navigateTo({
url: '/pages/privacyPolicy'
})
url: "/pages/privacyPolicy",
});
}
//
const agreed = () => {
showAuthorizationPopup.value = false
authorization.value = true
showPayment.value = true
showAuthorizationPopup.value = false;
authorization.value = true;
showPayment.value = true;
};
//
const cancel = () => {
showAuthorizationPopup.value = false
showAuthorizationPopup.value = false;
};
const toExample = () => {
uni.navigateTo({
url: '/pages/example'
})
url: "/pages/example",
});
};
onUnmounted(() => {
if (timer) {
@ -194,7 +412,6 @@ onUnmounted(() => {
<div class="mb-6 text-center text-3xl font-bold text-blue-700">
{{ featureData.product_name }}
</div>
<div class="card">
<div class="mb-4 text-lg font-semibold text-gray-800">基本信息</div>
<div class="mb-4 flex items-center" v-if="isHasInput('name')">
@ -205,6 +422,25 @@ onUnmounted(() => {
<label for="idCard" class="form-label">身份证号</label>
<input v-model="idCard" id="idCard" type="text" placeholder="请输入身份证号" class="form-input" />
</div>
<!-- 双人婚姻 -->
<div class="mb-4 flex items-center" v-if="isHasInput('nameMan')">
<label for="nameMan" class="form-label">男方姓名</label>
<input v-model="nameMan" id="nameMan" type="text" placeholder="请输入男方姓名" class="form-input" />
</div>
<div class="mb-4 flex items-center" v-if="isHasInput('idCardMan')">
<label for="idCardMan" class="form-label">男方身份证号</label>
<input v-model="idCardMan" id="idCardMan" type="text" placeholder="请输入男方身份证号" class="form-input" />
</div>
<div class="mb-4 flex items-center" v-if="isHasInput('nameWoman')">
<label for="nameWoman" class="form-label">女方姓名</label>
<input v-model="nameWoman" id="nameWoman" type="text" placeholder="请输入女方姓名" class="form-input" />
</div>
<div class="mb-4 flex items-center" v-if="isHasInput('idCardWoman')">
<label for="idCardWoman" class="form-label">女方身份证号</label>
<input v-model="idCardWoman" id="idCardWoman" type="text" placeholder="请输入女方身份证号" class="form-input" />
</div>
<!-- 双人婚姻 -->
<div class="mb-4 flex items-center" v-if="isHasInput('entName')">
<label for="entName" class="form-label">企业名称</label>
<input v-model="entName" id="entName" type="text" placeholder="请输入企业名称" class="form-input" />
@ -213,10 +449,38 @@ onUnmounted(() => {
<label for="entCode" class="form-label">统一社会信用代码</label>
<input v-model="entCode" id="entCode" type="text" placeholder="请输入统一社会信用代码" class="form-input" />
</div>
<div class="mb-4 flex items-center" v-if="isHasInput('carType')">
<label for="carType" class="form-label">汽车类型</label>
<van-field id="carType" v-model="carType" is-link readonly placeholder="点击选择汽车类型"
@click="showCarTypePicker = true" class="form-input" />
<van-popup v-model:show="showCarTypePicker" destroy-on-close round position="bottom">
<van-picker :model-value="carPickerVal" :columns="carTypeColumns"
@cancel="showCarTypePicker = false" @confirm="onConfirmCarType" />
</van-popup>
</div>
<div class="mb-4 flex items-center" v-if="isHasInput('carLicense')">
<!-- <label for="entCode" class="form-label">车牌号</label> -->
<CarNumberInput class="form-input" @number-input-result="carLicenseChange" :default-str="carLicense">
</CarNumberInput>
</div>
<div class="mb-4 flex items-center" v-if="isHasInput('bankCard')">
<label for="bankCard" class="form-label">银行卡号</label>
<input v-model="bankCard" id="bankCard" type="tel" placeholder="请输入银行卡号" class="form-input" />
</div>
<div class="mb-4 flex items-center" v-if="isHasInput('mobile')">
<label for="mobile" class="form-label">手机号</label>
<input v-model="mobile" id="mobile" type="tel" placeholder="请输入手机号" class="form-input" />
</div>
<div class="mb-4 flex items-center" v-if="isHasInput('date')">
<label for="date" class="form-label">业务日期</label>
<van-field id="date" v-model="dateVal" is-link readonly placeholder="点击选择日期"
@click="showDatePicker = true" class="form-input" />
<van-popup v-model:show="showDatePicker" destroy-on-close round position="bottom">
<van-date-picker v-model="startDate" :formatter="formatterDate" :min-date="minDate"
:max-date="maxDate" title="选择日期" @confirm="onConfirmDate" @cancel="showDatePicker = false" />
</van-popup>
</div>
<div class="mb-4 flex items-center" v-if="isHasInput('verificationCode')">
<label for="verificationCode" class="form-label">验证码</label>
<div class="flex-1 flex items-center">
@ -224,7 +488,11 @@ onUnmounted(() => {
class="form-input flex-1" />
<button class="ml-2 px-4 py-2 text-sm text-blue-500 disabled:text-gray-400"
:disabled="isCountingDown || !isPhoneNumberValid" @click="sendVerificationCode">
{{ isCountingDown ? `${countdown}s重新获取` : '获取验证码' }}
{{
isCountingDown
? `${countdown}s重新获取`
: "获取验证码"
}}
</button>
</div>
</div>
@ -256,27 +524,26 @@ onUnmounted(() => {
</div>
<div class="mb-6 flex items-center justify-between">
<div class="text-lg text-gray-500">
价格
</div>
<div class="text-lg text-gray-500">价格</div>
<div class="text-lg text-blue-600 font-semibold">
¥{{ featureData.sell_price }}
</div>
</div>
<div class="mb-4 text-lg text-gray-800 font-semibold">
报告主要内容
</div>
<div class="grid grid-cols-2 gap-4">
<div v-for="(feature, index) in featureData.features" :key="feature.id"
class="rounded-lg py-2 text-center text-sm text-gray-700 font-medium" :class="[
(Math.floor(index / 2) + (index % 2)) % 2 === 0
? 'bg-gradient-to-r from-blue-200 via-blue-200 to-blue-100'
: 'bg-gradient-to-r from-sky-200 via-sky-200 to-sky-100',
]">
{{ feature.name }}
<template v-if="featureData.features && featureData.features.length > 1">
<div class="mb-4 text-lg text-gray-800 font-semibold">
报告包含内容
</div>
</div>
<div class="grid grid-cols-2 gap-4">
<div v-for="(feature, index) in featureData.features" :key="feature.id"
class="rounded-lg py-2 text-center text-sm text-gray-700 font-medium" :class="[
(Math.floor(index / 2) + (index % 2)) % 2 === 0
? 'bg-gradient-to-r from-blue-200 via-blue-200 to-blue-100'
: 'bg-gradient-to-r from-sky-200 via-sky-200 to-sky-100',
]">
{{ feature.name }}
</div>
</div>
</template>
</div>
</div>
<!-- 底部弹出 -->
@ -292,6 +559,10 @@ onUnmounted(() => {
@apply w-20 text-sm font-medium text-gray-700 flex-shrink-0;
}
.form-input::placeholder {
color: var(--van-text-color-3);
}
.form-input {
@apply w-full border-b border-gray-200 px-2 py-2 focus:outline-none;
}

View File

@ -2,7 +2,7 @@
const featureMap = {
G09SC02: {
name: '单人婚姻',
component: defineAsyncComponent(() => import('@/ui/CBad.vue')),
component: defineAsyncComponent(() => import('@/ui/CMarriage.vue')),
},
G27BJ05: {
name: '借贷意向',
@ -32,14 +32,52 @@ const featureMap = {
},
G05HZ01: {
name: '股东人企关系',
component: defineAsyncComponent(() =>
import('@/ui/CRelatedEnterprises.vue')
),
component: defineAsyncComponent(() => import('@/ui/CRelatedEnterprises.vue')),
},
Q23SC01: {
name: '企业涉诉',
component: defineAsyncComponent(() => import('@/ui/CLawsuit.vue')),
},
G15BJ02: {
name: '手机三要素',
component: defineAsyncComponent(() => import('@/ui/CPhoneThreeElements.vue')),
},
KZEYS: {
name: '身份证二要素',
component: defineAsyncComponent(() => import('@/ui/CIDCardTwoElements.vue')),
},
G17BJ02: {
name: '手机号二要素',
component: defineAsyncComponent(() => import('@/ui/CPhoneTwoElements.vue')),
},
G10SC02: {
name: '双人婚姻核验',
component: defineAsyncComponent(() => import('@/ui/CDualMarriage.vue')),
},
P_C_B332: {
name: '人车核验',
component: defineAsyncComponent(() => import('@/ui/CP_C_B332.vue')),
},
FIN019: {
name: '银行卡黑名单',
component: defineAsyncComponent(() => import('@/ui/CFIN019.vue')),
},
G20GZ01: {
name: '银行卡四要素核验',
component: defineAsyncComponent(() => import('@/ui/CG20GZ01.vue')),
},
G03HZ01: {
name: '手机号码风险',
component: defineAsyncComponent(() => import('@/ui/CG03HZ01.vue')),
},
G19BJ02: {
name: '手机二次卡',
component: defineAsyncComponent(() => import('@/ui/CG19BJ02.vue')),
},
G02BJ02: {
name: '手机在网时长',
component: defineAsyncComponent(() => import('@/ui/CG02BJ02.vue')),
},
};
@ -51,7 +89,9 @@ const productId = ref(null);
const isDone = ref(true);
const reportData = ref([])
const reportParams = ref({})
const reportName = ref("")
const reportDateTime = ref(null)
const orderId = ref(null);
const orderNo = ref("")
const isEmpty = ref(false)
@ -82,7 +122,9 @@ const getReport = async () => {
if (data.value.code === 200) {
productId.value = data.value.data.product_id;
reportData.value = data.value.data.query_data
reportParams.value = data.value.data.query_params
reportName.value = data.value.data.product_name
reportDateTime.value = data.value.data.create_time
} else if (data.value.code === 200003) {
isEmpty.value = true
}
@ -94,15 +136,15 @@ const getReport = async () => {
<div class="min-h-full from-blue-100 to-white bg-gradient-to-b">
<!-- <CTabs :tabs="sortedTabs" type="blue-green" /> -->
<template v-if="isDone">
<div class="flex flex-col gap-y-4 p-4 pt-12">
<div class="flex flex-col gap-y-4 p-4 pt-8">
<div id="overdiv" class="title">报告概述</div>
<div class="card">
<div class="flex flex-col gap-y-2">
<div class="flex justify-between">
<span class="text-gray-700 font-bold">报告时间</span>
<span class="text-gray-600">2024年11月18日 23:11:23</span>
<span class="text-gray-600">{{ reportDateTime }}</span>
</div>
<div class="flex justify-between">
<div class="flex justify-between" v-if="!isEmpty">
<span class="text-gray-700 font-bold">报告项目</span>
<span class="text-gray-600">
{{ reportName }}</span>
@ -121,7 +163,8 @@ const getReport = async () => {
<LEmpty v-if="isEmpty" />
<template v-for="(item, index) in reportData" :key="index">
<div id="lawsuit" class="title">{{ featureMap[item.apiID].name }}</div>
<component :is="featureMap[item.apiID].component" :data="item.data"></component>
<component :is="featureMap[item.apiID].component" :data="item.data" :params="reportParams">
</component>
</template>
<div class="card">
<div>

View File

@ -7,6 +7,8 @@
</template>
<script setup>
import { useWebView } from "@/composables/useWebView";
useWebView()
onMounted(() => {
//
(function (d, t) {
@ -47,9 +49,11 @@ onMounted(() => {
font-size: 16px;
color: #333;
}
iframe {
background: #000000;
}
iframe::content .file-uploads.file-uploads-html5.text-black-900 {
display: none !important;
}

View File

@ -241,7 +241,7 @@ useWebView()
<div class="leading-relaxed">
如您对本协议及本服务有任何问题请通过邮箱
<text class="text-blue-500"> admin@iieeii.com </text>
APP联系客服联系海南省学宇思网络科技有限公司进行咨询
通过联系客服联系海南省学宇思网络科技有限公司进行咨询
海南省学宇思网络科技有限公司会尽最大努力解决您的问题
</div>
</div>

View File

@ -22,9 +22,14 @@
本平台提供全方位司法涉诉查询服务助您全面防范功能包括
</p>
<ul class="list-disc list-inside mt-4 space-y-2 text-gray-600">
<li>个人涉诉查看XXXXXXXXXXXXXXXXXXX</li>
<li>企业涉诉查看XXXXXXXXXXXXXXXXXXX</li>
<li>
<strong>个人涉诉</strong> 查看个人是否涉及诉讼案件了解其法律纠纷情况帮助您判断该个人的法律风险
</li>
<li>
<strong>企业涉诉</strong> 查看企业是否涉及诉讼案件了解企业的法律风险及潜在的经营问题帮助您评估与该企业合作的安全性
</li>
</ul>
</div>
</div>
</div>

View File

@ -24,8 +24,12 @@
本平台提供全方位风险评估查询服务助您全面防范功能包括
</p>
<ul class="list-disc list-inside mt-4 space-y-2 text-gray-600">
<li>个人不良查看XXXXXXXXXXXXXXXXXXX</li>
<li>股东人企关系查看XXXXXXXXXXXXXXXXXXX</li>
<li>
<strong>个人不良记录查询</strong> 通过查询个人的不良记录评估其风险等级高风险帮助您识别潜在的信用和法律风险确保合作方的合法合规
</li>
<li>
<strong>股东人企关系查询</strong> 通过个人关联的企业了解其可能涉及的风险帮助您判断该个人的风险水平特别是与高风险企业有联系的个人
</li>
</ul>
</div>
</div>

View File

@ -8,7 +8,8 @@
<!-- 功能菜单 -->
<div class="card">
<div class="grid grid-cols-3 gap-6">
<div v-for="(item, index) in menuItems" :key="index" class="flex flex-col items-center">
<div v-for="(item, index) in menuItems" :key="index" class="flex flex-col items-center"
@click="toInquire(item.product)">
<div class="bg-slate-100 rounded-full p-4">
<img :src="item.icon" :alt="item.title" class="w-10 h-10">
</div>
@ -23,15 +24,30 @@
本平台提供全方位核验工具服务助您全面防范功能包括
</p>
<ul class="list-disc list-inside mt-4 space-y-2 text-gray-600">
<li>手机三要素核验查看XXXXXXXXXXXXXXXXXXX</li>
<li>银行卡黑名单查看XXXXXXXXXXXXXXXXXXX</li>
<li><strong>手机三要素</strong> 查询手机号码的基本信息包括归属地运营商实名认证等帮助您评估号码的安全性</li>
<li><strong>银行卡黑名单</strong> 查询银行卡是否被列入黑名单帮助您识别潜在的金融风险</li>
<li><strong>身份证二要素</strong> 验证身份证信息的基本匹配情况确保身份真实性</li>
<li><strong>手机二要素</strong> 查询手机号码和身份证的匹配情况用于验证身份的真实性</li>
<li><strong>在网时长</strong> 查询手机号码的在网时长帮助评估号码的稳定性与历史</li>
<li><strong>手机二次卡</strong> 检查手机是否有二次卡防止诈骗等风险</li>
<li><strong>手机号码风险</strong> 评估手机号码的潜在风险包括是否与违法行为关联</li>
<li><strong>银行卡四要素</strong> 查询银行卡的四要素进一步验证银行账户的真实性</li>
<!-- <li><strong>自然人生存状态</strong> 查询个人的生存状态帮助验证其是否真实存在</li> -->
<!-- <li><strong>银行卡三要素</strong> 查询银行卡的三要素验证账户信息的安全性</li> -->
<!-- <li><strong>学历核验</strong> 验证学历信息的真实性确保所提供的学历符合实际</li> -->
<li><strong>人车核验</strong> 查询个人与车辆的关联情况帮助识别车辆的所有权和风险</li>
<li><strong>名下车辆</strong> 查询个人名下的所有车辆信息了解其车辆资产</li>
<li><strong>双人婚姻</strong> 查询双人婚姻状况帮助评估婚姻的法律状态和风险</li>
</ul>
</div>
</div>
</div>
</template>
<script setup>
import { useWebView } from "@/composables/useWebView";
useWebView()
import yhkhmdIcon from '@/assets/images/yhkhmd_icon.svg';
import sjsysIcon from '@/assets/images/sjsys_icon.svg'; //
import sfzeysIcon from '@/assets/images/sfzeys_icon.svg'; //
@ -48,41 +64,26 @@ import mxclIcon from '@/assets/images/mxcl_icon.svg'; // 名下车辆
import srhyIcon from '@/assets/images/srhy_icon.svg'; //
const menuItems = [
{ title: "手机三要素", icon: sjsysIcon },
{ title: "银行卡黑名单", icon: yhkhmdIcon },
{ title: "身份证二要素", icon: sfzeysIcon },
{ title: "手机二要素", icon: sjeysIcon },
{ title: "在网时长", icon: sjzwscIcon },
{ title: "手机二次卡", icon: sjeckIcon },
{ title: "手机号码风险", icon: sjhmfxIcon },
{ title: "银行卡四要素", icon: yhk4ysIcon },
{ title: "银行卡三要素", icon: yhksysIcon },
{ title: "自然人生存状态", icon: zrrscztIcon },
{ title: "学历核验", icon: xlhyIcon },
{ title: "人车核验", icon: rchyIcon },
{ title: "名下车辆", icon: mxclIcon },
{ title: "双人婚姻", icon: srhyIcon },
{ title: "手机三要素", icon: sjsysIcon, product: "toc_PhoneThreeElements" },
{ title: "银行卡黑名单", icon: yhkhmdIcon, product: "toc_BankCardBlacklist" },
{ title: "身份证二要素", icon: sfzeysIcon, product: "toc_IDCardTwoElements" },
{ title: "手机二要素", icon: sjeysIcon, product: "toc_PhoneTwoElements" },
{ title: "在网时长", icon: sjzwscIcon, product: "toc_NetworkDuration" },
{ title: "手机二次卡", icon: sjeckIcon, product: "toc_PhoneSecondaryCard" },
{ title: "手机号码风险", icon: sjhmfxIcon, product: "toc_PhoneNumberRisk" },
{ title: "银行卡四要素", icon: yhk4ysIcon, product: "toc_BankCardFourElements" },
// { title: "", icon: zrrscztIcon, product: "toc_NaturalLifeStatus" },
// { title: "", icon: yhksysIcon, product: "toc_BankCardThreeElements" },
// { title: "", icon: xlhyIcon, product: "toc_EducationVerification" },
{ title: "人车核验", icon: rchyIcon, product: "toc_PersonVehicleVerification" },
{ title: "名下车辆", icon: mxclIcon, product: "toc_VehiclesUnderName" },
{ title: "双人婚姻", icon: srhyIcon, product: "toc_DualMarriage" },
];
onMounted(() => {
uni.getEnv((platform) => {
console.log("当前运行环境", platform)
handleBridgeReady(platform)
});
})
const handleBridgeReady = (platform) => {
if (platform.h5) {
window.parent.postMessage({ loaded: true }, '*');
}
// else {
// uni.postMessage({
// data: {
// loaded: true,
// },
// });
// }
};
// console.log("uni", uni.navigateTo({ url: "/pages/index" }))
const toInquire = (product) => {
uni.navigateTo({ url: '/pages/inquire?p=' + product })
}
</script>
<style scoped></style>

View File

@ -19,7 +19,7 @@ export default defineConfig({
// changeOrigin: true,
// },
'/api/v1': {
target: 'http://127.0.0.1:8888', // 本地接口地址
target: 'http://192.168.10.20:8888', // 本地接口地址
changeOrigin: true,
},
},