This commit is contained in:
liangzai 2025-04-08 10:45:26 +08:00
parent 66c2df8d44
commit dc79995feb
60 changed files with 857 additions and 250 deletions

View File

@ -16,7 +16,7 @@
/>
<meta
name="keywords"
content="婚恋评估, 司法涉诉查询, 判决书查询, 婚姻状态查询, 失信人, 司法涉诉查询, 企业涉诉查询, 名下车辆核验, 车辆核验, 婚姻报告, 法律风险, 信用风险, 银行卡黑名单, 手机身份证核验, 学历核验, AI律师"
content="婚恋评估, 司法涉诉查询, 判决书查询, 婚姻状态查询, 失信人, 司法涉诉查询, 企业涉诉查询, 名下车辆核验, 车辆核验, 婚姻报告, 法律风险, 信用风险, 银行卡黑名单, 手机身份证核验, 学历核验, 智能助手"
/>
<meta name="author" content="天远数据" />
<meta

BIN
public/image/help/13.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

BIN
public/image/help/14.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

BIN
public/image/help/15.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

BIN
public/image/help/18.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 KiB

BIN
public/image/help/19.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 KiB

BIN
public/image/help/20.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 KiB

BIN
public/image/help/21.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 KiB

BIN
public/image/help/22.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 KiB

BIN
public/image/help/23.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 929 KiB

BIN
public/image/help/24.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

BIN
public/image/help/25.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 886 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 940 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

BIN
public/image/shot_nonal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
public/image/shot_svip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
public/image/shot_vip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

15
src/api/user.js Normal file
View File

@ -0,0 +1,15 @@
import axios from "axios";
// 获取API基础URL
const baseURL = import.meta.env.VITE_API_BASE_URL || "";
// 注销账号API
export function cancelAccount() {
return axios({
method: "post",
url: `${baseURL}/api/user/cancel`,
headers: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

View File

@ -1 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1740754612192" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="39491" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M887.456923 331.598922C867.952667 146.308492 707.042557 2.464607 516.876064 0.026575 307.205315-2.411457 134.105045 163.374716 134.105045 368.169401c0 134.091758 73.140959 253.555324 190.166494 319.382188l7.314096 75.578991c2.438032 14.628192 14.628192 24.38032 29.256383 24.380319h299.877932c14.628192 0 26.818352-12.19016 29.256383-24.380319l7.314096-75.578991c131.653726-70.702927 204.794685-207.232717 190.166494-355.952667zM321.833507 360.855305c0 17.066224-14.628192 29.256384-29.256384 29.256384s-29.256384-12.19016-29.256383-29.256384c0-9.752128 0-17.066224 2.438031-26.818351 2.438032-17.066224 17.066224-26.818352 34.132448-26.818352 17.066224 2.438032 29.256384 17.066224 26.818352 31.694416-2.438032 9.752128-4.876064 14.628192-4.876064 21.942287z m190.166493-185.290429c-70.702927 0-134.091758 36.570479-165.786174 97.521279-4.876064 9.752128-14.628192 14.628192-26.818351 14.628191-4.876064 0-9.752128 0-14.628192-2.438032-14.628192-7.314096-19.504256-24.38032-12.19016-39.008511 43.884575-78.017023 126.777662-126.777662 219.422877-126.777662 17.066224 0 29.256384 12.19016 29.256384 29.256383s-12.19016 26.818352-29.256384 26.818352zM343.775794 833.833507c-2.438032 9.752128-2.438032 17.066224-2.438032 26.818351 0 90.207183 75.578991 163.348142 168.224206 163.348142 92.645215 0 168.224206-73.140959 168.224206-163.348142 0-9.752128 0-19.504256-2.438032-26.818351H343.775794z" fill="#F5B53A" p-id="39492"></path></svg>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1741855510780" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2636" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M853.64224 76.7488H155.25888c-49.03424 0-88.75008 40.14592-88.75008 89.18528l-0.41472 766.18752c-0.00512 13.45024 16.256 20.18816 25.76384 10.68032l148.16256-148.16256a15.09376 15.09376 0 0 1 10.6752-4.41856h602.94656c57.34912 0 104.26368-46.9248 104.26368-104.2688V181.02784c0-57.35424-46.91456-104.27904-104.26368-104.27904z m-299.33056 544.1792a15.09376 15.09376 0 0 1-15.08864 15.08864H472.73472a15.09376 15.09376 0 0 1-15.09376-15.08864v-60.5696a15.09376 15.09376 0 0 1 15.09376-15.08864h66.4832a15.09376 15.09376 0 0 1 15.08864 15.08864v60.5696h0.00512z m39.45984-199.94112c-35.16928 24.76032-51.65056 48.84992-49.39776 72.30464 0.05632 0.4608 0.08704 0.9216 0.08704 1.3824a15.08864 15.08864 0 0 1-15.09376 15.08864h-48.73216a15.08352 15.08352 0 0 1-15.08864-15.08864v-6.60992c-1.32608-40.61184 15.6672-72.77056 50.92352-96.41984 0.24064-0.16384 0.49152-0.33792 0.72704-0.51712 32.6144-24.86784 48.2816-48.45056 46.99136-70.74816-2.62144-27.33056-18.0992-42.40896-46.4384-45.29152a16.45568 16.45568 0 0 0-1.81248-0.08192c-31.42144 0.3584-52.42368 19.4816-62.98112 57.3696a15.13472 15.13472 0 0 1-17.4592 10.85952L374.1696 331.23328a15.11424 15.11424 0 0 1-11.70944-18.61632c20.54144-80.15872 76.60032-118.99392 168.17152-116.5312 81.30048 5.25312 126.0032 41.89696 134.08256 109.88544 0.0512 0.38912 0.08192 0.78848 0.10752 1.1776 2.3808 44.47744-21.2992 82.41152-71.05024 113.83808z" fill="#397B8B" p-id="2637"></path></svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 929 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 KiB

View File

@ -2,20 +2,16 @@
<van-popup v-model:show="show" round position="bottom">
<div class="max-h-[calc(100vh-100px)] m-4 ">
<div class="p-4">
<canvas ref="posterCanvas" class="rounded-xl shadow h-[500px] m-auto"></canvas>
<van-swipe class="poster-swiper rounded-xl shadow" indicator-color="white" @change="onSwipeChange">
<van-swipe-item v-for="(_, index) in posterImages" :key="index">
<canvas :ref="el => posterCanvasRefs[index] = el"
class="poster-canvas rounded-xl h-[800px] m-auto"></canvas>
</van-swipe-item>
</van-swipe>
</div>
<!-- <div class="m-2"></div> -->
<van-divider>分享到好友</van-divider>
<div class="flex items-center justify-around">
<!-- <div class="flex flex-col items-center justify-center" @click="toPromote">
<img src="@/assets/images/icon_share_wechat.svg" class="w-12 h-12 rounded-full" />
<div class="text-center mt-1">微信好友</div>
</div>
<div class="flex flex-col items-center justify-center">
<img src="@/assets/images/icon_share_friends.svg" class="w-12 h-12 rounded-full" />
<div class="text-center mt-1">微信朋友圈</div>
</div> -->
<div class="flex flex-col items-center justify-center" @click="savePoster">
<img src="@/assets/images/icon_share_img.svg" class="w-10 h-10 rounded-full" />
<div class="text-center mt-1 text-gray-600 text-xs">保存图片</div>
@ -30,8 +26,10 @@
</template>
<script setup>
import { ref, watch, nextTick } from 'vue';
import { ref, watch, nextTick, computed, onMounted, toRefs } from 'vue';
import QRCode from 'qrcode';
import { showToast } from 'vant';
const props = defineProps({
linkIdentifier: {
type: String,
@ -43,9 +41,10 @@ const props = defineProps({
},
});
const { linkIdentifier, mode } = toRefs(props);
const posterCanvas = ref(null); // canvas
let posterGenerated = ref(false); //
const show = defineModel('show')
const posterCanvasRefs = ref([]); // canvas
const currentIndex = ref(0); //
const postersGenerated = ref([]); // onMounted
const show = defineModel('show');
const url = computed(() => {
const baseUrl = window.location.origin; //
return mode.value === "promote"
@ -53,35 +52,98 @@ const url = computed(() => {
: `${baseUrl}/agent/invitationAgentApply/`;
});
const qrcodeImage = ref(null);
const loadPosterImage = async () => {
if (mode.value === "promote") {
const module = await import("@/assets/images/tg_qrcode_1.png");
return module.default;
} else {
const module = await import("@/assets/images/yq_qrcode_1.png");
return module.default;
//
const posterImages = ref([]);
// QR
const qrCodePositions = ref({
// promote (tg_qrcode)
promote: [
{ x: 180, y: 1440, size: 300 }, // tg_qrcode_1.png
{ x: 525, y: 1955, size: 500 }, // tg_qrcode_2.jpg
{ x: 525, y: 1955, size: 500 }, // tg_qrcode_3.jpg
{ x: 525, y: 1955, size: 500 }, // tg_qrcode_4.jpg
{ x: 525, y: 1955, size: 500 }, // tg_qrcode_5.jpg
{ x: 525, y: 1955, size: 500 }, // tg_qrcode_6.jpg
{ x: 255, y: 940, size: 250 }, // tg_qrcode_7.jpg
{ x: 255, y: 940, size: 250 }, // tg_qrcode_8.jpg
],
// invitation (yq_qrcode)
invitation: [
{ x: 360, y: -1370, size: 360 }, // yq_qrcode_1.png
]
});
//
const onSwipeChange = (index) => {
currentIndex.value = index;
if (!postersGenerated.value[index]) {
generatePoster(index);
}
};
//
const loadPosterImages = async () => {
const images = [];
const basePrefix = mode.value === "promote" ? "tg_qrcode_" : "yq_qrcode_";
//
const imageCount = mode.value === "promote" ? 8 : 1;
//
for (let i = 1; i <= imageCount; i++) {
// .png
try {
const module = await import(`@/assets/images/${basePrefix}${i}.png`);
images.push(module.default);
continue; // png jpg
} catch (error) {
console.warn(`Image ${basePrefix}${i}.png not found, trying jpg...`);
}
// .png .jpg
try {
const module = await import(`@/assets/images/${basePrefix}${i}.jpg`);
images.push(module.default);
} catch (error) {
console.warn(`Image ${basePrefix}${i}.jpg not found either, using fallback.`);
if (i === 1) {
//
const emptyImg = new Image();
emptyImg.width = 600;
emptyImg.height = 800;
images.push(emptyImg.src);
} else if (images.length > 0) {
images.push(images[0]);
}
}
}
return images;
};
onMounted(async () => {
qrcodeImage.value = await loadPosterImage()
posterImages.value = await loadPosterImages();
// postersGenerated
postersGenerated.value = Array(posterImages.value.length).fill(false);
});
//
const generatePoster = async () => {
const generatePoster = async (index) => {
//
if (posterGenerated.value) return;
if (postersGenerated.value[index]) return;
// DOM
await nextTick();
const canvas = posterCanvas.value;
const canvas = posterCanvasRefs.value[index];
if (!canvas) return; // canvas
const ctx = canvas.getContext('2d');
// 1.
const posterImg = new Image();
posterImg.src = qrcodeImage.value;
posterImg.src = posterImages.value[index];
posterImg.onload = () => {
// canvas
@ -102,13 +164,18 @@ const generatePoster = async () => {
const qrCodeImg = new Image();
qrCodeImg.src = qrCodeUrl;
qrCodeImg.onload = () => {
const qrX = mode.value === "promote" ? 180 : 360; // ****
const qrY = mode.value === "promote" ? posterImg.height - 480 : posterImg.height - 1370;
const qrSize = mode.value === "promote" ? 300 : 360
ctx.drawImage(qrCodeImg, qrX, qrY, qrSize, qrSize);
//
const positions = qrCodePositions.value[mode.value];
const position = positions[index] || positions[0]; // 使
// Y
const qrY = position.y < 0 ? posterImg.height + position.y : position.y;
//
ctx.drawImage(qrCodeImg, position.x, qrY, position.size, position.size);
//
posterGenerated.value = true;
postersGenerated.value[index] = true;
};
});
};
@ -116,8 +183,8 @@ const generatePoster = async () => {
// show show true
watch(show, (newVal) => {
if (newVal && !posterGenerated.value) {
generatePoster(); //
if (newVal && !postersGenerated.value[currentIndex.value]) {
generatePoster(currentIndex.value); //
}
});
@ -129,19 +196,22 @@ const toPromote = () => {
//
const savePoster = () => {
const canvas = posterCanvas.value;
const canvas = posterCanvasRefs.value[currentIndex.value];
const dataURL = canvas.toDataURL('image/png'); // canvas
const a = document.createElement('a');
a.href = dataURL;
a.download = '天远数据查询.png';
a.click();
};
const generalUrl = () => {
return url.value + encodeURIComponent(linkIdentifier.value)
return url.value + encodeURIComponent(linkIdentifier.value);
}
const copyUrl = () => {
copyToClipboard(generalUrl())
copyToClipboard(generalUrl());
}
//
const copyToClipboard = (text) => {
if (navigator.clipboard && window.isSecureContext) {
@ -170,5 +240,14 @@ const copyToClipboard = (text) => {
</script>
<style lang="scss" scoped>
/* 这里是你自定义的样式 */
.poster-swiper {
height: 500px;
width: 100%;
}
.poster-canvas {
width: 100%;
height: 100%;
object-fit: contain;
}
</style>

View File

@ -1,13 +1,10 @@
// src/composables/useEnv.js
import { ref, onMounted } from "vue";
import { ref, computed } from "vue";
export function useEnv() {
const isWeChat = ref(false);
onMounted(() => {
// 检测是否是微信环境
const userAgent = navigator.userAgent.toLowerCase();
isWeChat.value = userAgent.includes("micromessenger");
});
const isWeChat = /micromessenger/i.test(userAgent);
return {
isWeChat,

View File

@ -54,8 +54,8 @@ const route = useRoute();
const tabbar = ref('index');
const menu = reactive([
{ title: '首页', icon: 'home-o', name: 'index' },
{ title: '推广', icon: 'balance-o', name: 'agent' },
{ title: 'AI律师', icon: 'chat-o', name: 'ai' },
{ title: '资产', icon: 'gold-coin-o', name: 'agent' },
{ title: '智能助手', icon: 'chat-o', name: 'ai' },
{ title: '我的', icon: 'user-o', name: 'me' },
]);
@ -73,7 +73,7 @@ const tabChange = (name) => {
//
const toComplaint = () => {
window.location.href = 'https://work.weixin.qq.com/kfid/kfc5c19b2b93a5e73b9' //
window.location.href = 'https://work.weixin.qq.com/kfid/kfc8a32720024833f57' //
// router.push({ name: 'complaint' }); // 使 Vue Router
};

View File

@ -56,7 +56,18 @@ const router = createRouter({
component: () => import("@/views/Help.vue"),
meta: { title: "帮助中心" },
},
{
path: "/help/detail",
name: "helpDetail",
component: () => import("@/views/HelpDetail.vue"),
meta: { title: "帮助中心" },
},
{
path: "/help/guide",
name: "helpGuide",
component: () => import("@/views/HelpGuide.vue"),
meta: { title: "引导指南" },
},
{
path: "/service",
name: "service",

View File

@ -23,11 +23,46 @@ export const useAgentStore = defineStore("agent", {
this.status = data.value.data.status; // 获取代理状态 0=待审核1=审核通过2=审核未通过3=未申请
this.agentID = data.value.data.agent_id;
this.mobile = data.value.data.mobile;
// 保存到localStorage
localStorage.setItem(
"agentInfo",
JSON.stringify({
isAgent: this.isAgent,
level: this.level,
status: this.status,
agentID: this.agentID,
mobile: this.mobile,
})
);
} else {
console.log("Error fetching agent info", data.value);
}
}
this.isLoaded = true;
},
// 更新代理信息
updateAgentInfo(agentInfo) {
if (agentInfo) {
this.isAgent = agentInfo.isAgent || false;
this.level = agentInfo.level || "";
this.status = agentInfo.status || 3;
this.agentID = agentInfo.agentID || null;
this.mobile = agentInfo.mobile || "";
this.isLoaded = true;
}
},
// 重置代理信息
resetAgent() {
this.isLoaded = false;
this.level = "";
this.status = 3;
this.isAgent = false;
this.ancestorID = null;
this.agentID = null;
this.mobile = "";
},
},
});

View File

@ -17,8 +17,33 @@ export const useUserStore = defineStore("user", {
this.userName = userinfo.nickName || "";
this.userAvatar = userinfo.userAvatar;
this.isLoggedIn = true;
// 保存到localStorage
localStorage.setItem(
"userInfo",
JSON.stringify({
nickName: this.userName,
avatar: this.userAvatar,
})
);
}
}
},
// 更新用户信息
updateUserInfo(userInfo) {
if (userInfo) {
this.userName = userInfo.nickName || "";
this.userAvatar = userInfo.avatar || "";
this.isLoggedIn = true;
}
},
// 重置用户信息
resetUser() {
this.userName = "";
this.userAvatar = "";
this.isLoggedIn = false;
},
},
});

87
src/ui/CIDV044.vue Normal file
View File

@ -0,0 +1,87 @@
<script setup>
import LTitle from "@/components/LTitle.vue";
const props = defineProps({
data: {
type: Object,
required: true,
},
});
const { data } = props;
//
const statusMap = {
0: {
text: "未婚或尚未登记结婚",
bgClass: "bg-yellow-100",
textClass: "text-yellow-700",
description: "未进行民政登记婚姻",
},
1: {
text: "已婚",
bgClass: "bg-green-100",
textClass: "text-green-700",
description: "已登记婚姻,家庭幸福美满",
},
2: {
text: "离异",
bgClass: "bg-red-100",
textClass: "text-red-700",
description: "离异状态,未来生活可期",
},
3: {
text: "离婚冷静期",
bgClass: "bg-blue-100",
textClass: "text-blue-700",
description: "目前处于离婚冷静期,请谨慎决策",
},
};
// `data.status`
const currentStatus =
data.status !== undefined
? statusMap[data.status] || statusMap["0"]
: {
text: "无相关记录",
bgClass: "bg-gray-200",
textClass: "text-gray-500",
description: "暂无婚姻相关记录",
};
</script>
<template>
<div class="card">
<div class="status-info flex flex-col items-center ">
<div
:class="`status-label rounded-full px-6 py-3 text-center font-bold shadow-md ${currentStatus.bgClass} ${currentStatus.textClass}`">
{{ currentStatus.text }}
</div>
<p class="status-description mt-3 text-sm text-gray-600">
{{ currentStatus.description }}
</p>
</div>
</div>
</template>
<style lang="scss" scoped>
.status-info {
text-align: center;
}
.status-label {
font-size: 1.25rem;
padding: 0.75rem 1.5rem;
border-radius: 9999px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.status-description {
color: #4a5568;
margin-top: 0.5rem;
font-weight: 500;
}
.additional-info p {
margin-top: 0.5rem;
}
</style>

View File

@ -14,7 +14,7 @@
<script setup>
function toService() {
// window.location.href = '/service' //
window.location.href = 'https://work.weixin.qq.com/kfid/kfc5c19b2b93a5e73b9' //
window.location.href = 'https://work.weixin.qq.com/kfid/kfc8a32720024833f57' //
}
</script>

View File

@ -1,5 +1,16 @@
<template>
<div class="flex flex-col box-border from-blue-100 to-white bg-gradient-to-b pt-4 flex-1 pb-4">
<!-- 顶部标题 -->
<div class="flex border-blue-300 mx-4 p-3 bg-blue-300 text-white rounded-xl mb-4 justify-between items-center">
<div class="flex items-center">
<img src="@/assets/images/ai_qinggan.png" class="w-10 h-10 rounded-xl mr-2" alt="智能助手" />
<span class="text-lg font-medium">智能助手</span>
</div>
<div @click="contactCustomerService"
class="flex items-center px-3 py-1 bg-green-500 rounded-lg cursor-pointer shadow-sm">
<span class="text-white text-sm">联系人工客服</span>
</div>
</div>
<div class="mx-4 flex flex-col flex-1 rounded-xl shadow-lg">
<!-- Chat Window -->
<div class="w-full text-center py-2 text-slate-800 font-bold text-xl bg-white rounded-t-xl">AI律师</div>
@ -8,7 +19,7 @@
<div class=" flex-1 overflow-y-auto">
<div v-for="(message, index) in messages" :key="index" class="mb-4">
<div v-if="message.sender === 'ai'" class="flex justify-start items-start">
<img class="w-10 h-10 rounded-xl mr-2" src="@/assets/images/ai_picture.webp" alt="AI律师">
<img class="w-10 h-10 rounded-xl mr-2" src="@/assets/images/ai_qinggan.png" alt="AI律师">
<div
class="inline-block max-w-max rounded-xl bg-white p-2 text-left text-green-600 font-medium shadow-md">
<!-- If AI message, show loading or text -->
@ -78,7 +89,7 @@ async function sendMessage() {
body: JSON.stringify({
prompt: userMessage.value,
platform_id: 2,
roleid: 1,
role_id: 2,
openid: 'openid' + localStorage.getItem("token"),
userid: 'userid' + localStorage.getItem("token"),
sessionid: sessionID.value // sessionID
@ -150,7 +161,9 @@ onBeforeUnmount(() => {
}
});
const contactCustomerService = () => {
window.location.href = 'https://work.weixin.qq.com/kfid/kfc8a32720024833f57' //
}
</script>
<style scoped>

View File

@ -86,7 +86,12 @@ const featureMap = {
CAR061: {
name: '名下车辆',
component: defineAsyncComponent(() => import('@/ui/CCAR061.vue')),
}
},
IDV044: {
name: '婚姻状态',
component: defineAsyncComponent(() => import('@/ui/CIDV044.vue')),
remark: '查询结果为"未婚或尚未登记结婚"时,表示婚姻登记处暂无相关的登记记录。婚姻状态信息由婚姻登记处逐级上报,可能存在数据遗漏或更新滞后。当前可查询的婚姻状态包括:未婚或尚未登记结婚、已婚、离异、离异冷静期。如您对查询结果有疑问,请联系客服反馈。'
},
};
@ -97,7 +102,7 @@ import GaugeChart from "@/components/GaugeChart.vue";
const productId = ref(null);
const isDone = ref(true);
const isDone = ref(false);
const active = ref(null)
const reportData = ref([])
@ -106,9 +111,9 @@ const reportName = ref("")
const reportDateTime = ref(null)
const feature = ref("")
const isEmpty = ref(false)
const reportScore = ref(75); //
const reportScore = ref(0); //
onMounted(() => {
onBeforeMount(() => {
const query = new URLSearchParams(window.location.search);
feature.value = query.get("feature");
console.log("feature", feature.value)
@ -138,17 +143,17 @@ const getReport = async () => {
} else if (data.value.code === 200003) {
isEmpty.value = true
}
isDone.value = true
}
}
//
const calculateScore = (reportData) => {
// 0
// 00
let score = 0;
// 90
// 9090
const maxScore = 90;
//
//
const relativeWeights = {
//
'G34BJ03': 250, //
@ -179,7 +184,7 @@ const calculateScore = (reportData) => {
const availableAPIs = reportData.map(item => item.data.apiID).filter(id => relativeWeights[id]);
//
if (availableAPIs.length === 0) return 60; // 60
if (availableAPIs.length === 0) return 30; // 30
//
let totalWeight = 0;
@ -197,7 +202,7 @@ const calculateScore = (reportData) => {
actualWeights[apiID] = relativeWeights[apiID] * pointValue;
});
//
// -
reportData.forEach(item => {
const apiID = item.data.apiID;
const data = item.data.data;
@ -205,7 +210,7 @@ const calculateScore = (reportData) => {
//
if (!actualWeights[apiID]) return;
// API ID
// API ID
switch (apiID) {
case 'G09SC02': //
//
@ -213,61 +218,58 @@ const calculateScore = (reportData) => {
case 'G27BJ05': //
if (data) {
// 0
let noRisk = true;
//
let hasRisk = false;
for (const key in data) {
if (data[key] !== 0 && data[key] !== '0') {
noRisk = false;
if (data[key] !== 0 && data[key] !== '0' &&
key.indexOf('allnum') > -1 &&
!isNaN(parseInt(data[key])) &&
parseInt(data[key]) > 0) {
hasRisk = true;
break;
}
}
if (noRisk || !Object.keys(data).length) {
if (hasRisk) {
score += actualWeights[apiID];
}
} else {
//
score += actualWeights[apiID];
}
break;
case 'G28BJ05': //
if (data) {
// 0
let noRisk = true;
//
let hasRisk = false;
for (const key in data) {
if (data[key] !== 0 && data[key] !== '0') {
noRisk = false;
if (data[key] !== 0 && data[key] !== '0' &&
(key.indexOf('lendamt') > -1 || key.indexOf('num') > -1) &&
!isNaN(parseInt(data[key])) &&
parseInt(data[key]) > 0) {
hasRisk = true;
break;
}
}
if (noRisk || !Object.keys(data).length) {
if (hasRisk) {
score += actualWeights[apiID];
}
} else {
//
score += actualWeights[apiID];
}
break;
case 'G26BJ05': //
if (data) {
// 0
//
const excludeFields = ['swift_number', 'code', 'flag_specialList_c'];
let noRisk = true;
let hasRisk = false;
for (const key in data) {
if (!excludeFields.includes(key) && data[key] !== 0 && data[key] !== '0') {
noRisk = false;
hasRisk = true;
break;
}
}
if (noRisk || !Object.keys(data).length) {
if (hasRisk) {
score += actualWeights[apiID];
}
} else {
//
score += actualWeights[apiID];
}
break;
@ -276,23 +278,20 @@ const calculateScore = (reportData) => {
//
switch (data.risk_level) {
case 'A': //
score += actualWeights[apiID];
//
break;
case 'F': //
score += actualWeights[apiID] * 0.7;
score += actualWeights[apiID] * 0.3;
break;
case 'C': //
case 'D': //
score += actualWeights[apiID] * 0.3;
score += actualWeights[apiID] * 0.7;
break;
case 'B': //
case 'E': //
//
score += actualWeights[apiID];
break;
}
} else {
//
score += actualWeights[apiID];
}
break;
@ -327,12 +326,9 @@ const calculateScore = (reportData) => {
hasRisk = true;
}
if (!hasRisk) {
if (hasRisk) {
score += actualWeights[apiID];
}
} else {
//
score += actualWeights[apiID];
}
break;
@ -341,38 +337,29 @@ const calculateScore = (reportData) => {
// filterType
switch (data.filterType) {
case '0': //
score += actualWeights[apiID];
break;
case '3': //
score += actualWeights[apiID] * 0.7;
break;
case '2': //
score += actualWeights[apiID] * 0.3;
break;
case '1': //
//
break;
}
} else {
//
case '3': //
score += actualWeights[apiID] * 0.3;
break;
case '2': //
score += actualWeights[apiID] * 0.7;
break;
case '1': //
score += actualWeights[apiID];
break;
}
}
break;
case 'G19BJ02': //
if (data && data.is_second_card === false) {
score += actualWeights[apiID];
} else if (!data) {
//
if (data && data.is_second_card === true) {
score += actualWeights[apiID];
}
break;
case 'G02BJ02': //
if (data && data.online_months >= 6) {
score += actualWeights[apiID];
} else if (!data) {
//
if (data && data.online_months < 6) {
score += actualWeights[apiID];
}
break;
@ -381,19 +368,13 @@ const calculateScore = (reportData) => {
case 'G17BJ02': //
case 'KZEYS': //
case 'G20GZ01': //
if (data && data.is_consistent) {
score += actualWeights[apiID];
} else if (!data) {
//
if (data && data.is_consistent === false) {
score += actualWeights[apiID];
}
break;
case 'FIN019': //
if (data && data.is_blacklisted === false) {
score += actualWeights[apiID];
} else if (!data) {
//
if (data && data.is_blacklisted === true) {
score += actualWeights[apiID];
}
break;
@ -580,7 +561,7 @@ const maskValue = computed(() => {
<div class="text-sm text-gray-600">身份证信息核验通过</div>
</div>
</div>
<div class="flex items-center bg-blue-100 rounded-xl px-4 py-2 flex-1">
<!-- <div class="flex items-center bg-blue-100 rounded-xl px-4 py-2 flex-1">
<div
class="bg-green-500 w-12 h-12 text-white text-xl flex items-center justify-center rounded-full mr-4">
</div>
@ -589,7 +570,7 @@ const maskValue = computed(() => {
<div class="text-sm text-gray-600">被查询人姓名与运营商提供的一致</div>
<div class="text-sm text-gray-600">被查询人身份证与运营商提供的一致</div>
</div>
</div>
</div> -->
</div>
</div>
</template>
@ -597,13 +578,14 @@ const maskValue = computed(() => {
</div>
<LRemark content="如查询的姓名/身份证与运营商提供的不一致,可能会存在报告内容不匹配的情况" />
</van-tab>
<van-tab v-for="(item, index) in reportData" :key="index" :title="featureMap[item.data.apiID].name">
<div id="lawsuit" class="title mb-4">{{ featureMap[item.data.apiID].name }}</div>
<component :is="featureMap[item.data.apiID].component" :data="item.data.data"
<van-tab v-for="(item, index) in reportData" :key="index"
:title="featureMap[item.data.apiID]?.name">
<div id="lawsuit" class="title mb-4">{{ featureMap[item.data.apiID]?.name }}</div>
<component :is="featureMap[item.data.apiID]?.component" :data="item.data.data"
:params="reportParams">
</component>
<LRemark v-if="featureMap[item.data.apiID].remark"
:content="featureMap[item.data.apiID].remark" />
<LRemark v-if="featureMap[item.data.apiID]?.remark"
:content="featureMap[item.data.apiID]?.remark" />
</van-tab>
<div class="card">
<div>

View File

@ -1,11 +1,114 @@
<template>
<div>
帮助中心
<div class="help-center">
<van-tabs v-model:active="activeTab" sticky :offset-top="46">
<van-tab v-for="(category, index) in categories" :key="index" :title="category.title" :name="category.name">
<van-cell-group inset class="help-list" size="large">
<van-cell v-for="item in category.items" :key="item.id" :title="item.title" is-link
@click="goToDetail(item.id, item.type)" class="help-item">
<template #label>
<van-tag v-if="item.type === 'guide'" type="primary" size="small"
class="guide-tag">引导指南</van-tag>
</template>
</van-cell>
</van-cell-group>
</van-tab>
</van-tabs>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const activeTab = ref('report')
const categories = [
{
title: '推广报告',
name: 'report',
items: [
{ id: 'report_guide', title: '直推报告页面引导', type: 'guide' },
{ id: 'invite_guide', title: '邀请下级页面引导', type: 'guide' },
{ id: 'report_push', title: '如何推广报告' },
{ id: 'report_efficiency', title: '报告推广效率飙升指南' },
{ id: 'report_calculation', title: '推广报告的收益是如何计算的?' },
{ id: 'report_cost', title: '推广报告的成本是如何计算的?' },
{ id: 'report_secret', title: '报告推广秘籍大公开' },
{ id: 'report_types', title: '天远数据有哪些大数据报告类型' },
]
},
{
title: '邀请下级',
name: 'invite',
items: [
{ id: 'invite_earnings', title: '邀请下级赚取收益' }
]
},
{
title: '其他',
name: 'other',
items: [
{ id: 'vip_guide', title: '如何成为VIP代理和SVIP代理?' }
]
}
]
const goToDetail = (id, type) => {
if (type === 'guide') {
router.push({
path: '/help/guide',
query: { id }
})
} else {
router.push({
path: '/help/detail',
query: { id }
})
}
}
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
.help-center {
min-height: 100vh;
background-color: #f7f8fa;
.help-list {
margin-top: 12px;
.guide-tag {
margin-top: 4px;
}
}
:deep(.help-item) {
.van-cell__title {
font-size: 16px;
}
}
}
.help-detail {
padding: 20px;
&-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
h3 {
margin: 0;
font-size: 18px;
}
}
&-content {
white-space: pre-line;
line-height: 1.6;
color: #666;
}
}
</style>

80
src/views/HelpDetail.vue Normal file
View File

@ -0,0 +1,80 @@
<template>
<div class="help-detail">
<h2>{{ currentHelp.title }}</h2>
<template v-if="Array.isArray(currentHelp.images)">
<img v-for="(image, index) in currentHelp.images" :key="index" :src="image" :alt="currentHelp.title"
class="help-image">
</template>
<img v-else-if="currentHelp.image" :src="currentHelp.image" :alt="currentHelp.title" class="help-image">
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const currentHelp = ref({
title: '',
image: '',
images: null
})
//
const imageMap = {
report_calculation: '/image/help/report-calculation.jpg',
report_efficiency: '/image/help/report-efficiency.jpg',
report_cost: '/image/help/report-cost.jpg',
report_types: '/image/help/report-types.jpg',
report_push: '/image/help/report-push.jpg',
report_secret: ['/image/help/report-secret-1.jpg', '/image/help/report-secret-2.jpg'],
invite_earnings: '/image/help/invite-earnings.jpg',
direct_earnings: '/image/help/direct-earnings.jpg',
vip_guide: '/image/help/vip-guide.jpg'
}
//
const titleMap = {
report_calculation: '推广报告的收益是如何计算的?',
report_efficiency: '报告推广效率飙升指南',
report_cost: '推广报告的成本是如何计算的?',
report_types: '天远数据有哪些大数据报告类型',
report_push: '如何推广报告',
report_secret: '报告推广秘籍大公开',
invite_earnings: '邀请下级赚取收益',
direct_earnings: '直推报告赚取收益',
vip_guide: '如何成为VIP代理和SVIP代理?'
}
onMounted(() => {
const id = route.query.id
if (id && titleMap[id]) {
currentHelp.value = {
title: titleMap[id],
image: Array.isArray(imageMap[id]) ? null : imageMap[id],
images: Array.isArray(imageMap[id]) ? imageMap[id] : null
}
}
})
</script>
<style lang="scss" scoped>
.help-detail {
min-height: 100vh;
padding: 20px;
background-color: #fff;
h2 {
margin: 0 0 20px;
font-size: 22px;
color: #323233;
font-weight: 500;
}
.help-image {
width: 100%;
border-radius: 8px;
margin-bottom: 12px;
}
}
</style>

103
src/views/HelpGuide.vue Normal file
View File

@ -0,0 +1,103 @@
<template>
<div class="help-guide">
<div class="guide-content" @click="handleImageClick">
<img :src="currentStep.image" :alt="currentStep.title" class="guide-image">
</div>
</div>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
const router = useRouter()
const currentStepIndex = ref(0)
//
const guideSteps = {
report_guide: [
{
title: '第一步:进入直推报告页面',
image: '/image/help/report-step1.jpg'
},
{
title: '第二步:选择报告类型',
image: '/image/help/report-step2.jpg'
},
{
title: '第三步:填写推广信息',
image: '/image/help/report-step3.jpg'
},
{
title: '第四步:完成推广',
image: '/image/help/report-step4.jpg'
}
],
invite_guide: [
{
title: '第一步:进入邀请页面',
image: '/image/help/invite-step1.jpg'
},
{
title: '第二步:获取邀请码',
image: '/image/help/invite-step2.jpg'
},
{
title: '第三步:分享邀请链接',
image: '/image/help/invite-step3.jpg'
},
]
}
const currentGuide = computed(() => {
const id = route.query.id
return guideSteps[id] || []
})
const totalSteps = computed(() => currentGuide.value.length)
const currentStep = computed(() => currentGuide.value[currentStepIndex.value])
const handleImageClick = () => {
if (currentStepIndex.value < totalSteps.value - 1) {
currentStepIndex.value++
} else {
//
router.back()
}
}
const onClickLeft = () => {
router.back()
}
onMounted(() => {
const id = route.query.id
if (!guideSteps[id]) {
router.back()
}
})
</script>
<style lang="scss" scoped>
.help-guide {
background-color: #666666;
display: flex;
flex-direction: column;
height: calc(100vh - 46px);
.guide-content {
flex: 1;
height: calc(100vh - 46px);
overflow: hidden;
position: relative;
.guide-image {
width: 100%;
object-fit: contain;
display: block;
}
}
}
</style>

View File

@ -7,7 +7,7 @@
<div class="relative">
<!-- 头像容器添加overflow-hidden解决边框问题 -->
<div class="overflow-hidden rounded-full p-0.5" :class="levelGradient.border">
<img :src="userAvatar || headShot" alt="User Avatar"
<img :src="userAvatar || getDefaultAvatar()" alt="User Avatar"
class="h-24 w-24 rounded-full border-4 border-white">
</div>
@ -28,7 +28,7 @@
</p>
</div>
</div>
<VipBanner v-if="isAgent && level === 'normal'" />
<VipBanner v-if="isAgent && (level === 'normal' || level === '')" />
<!-- 功能菜单 -->
<div class="features-section space-y-3">
<template v-if="isAgent && ['VIP', 'SVIP'].includes(level)">
@ -45,10 +45,18 @@
<button class="feature-item hover:bg-blue-50" @click="toUserAgreement">
📜 用户协议
</button>
<button class="feature-item hover:bg-blue-50" @click="toService">
💬 联系客服
<button class="feature-item hover:bg-blue-50" @click="toPrivacyPolicy">
🔒 隐私政策
</button>
<button v-if="!isWeChat" class="feature-item hover:bg-red-50 text-red-600" @click="handleLogout">
<button class="feature-item hover:bg-blue-50" @click="toAi">
💬 智能客服
</button>
<button v-if="isLoggedIn" class="feature-item hover:bg-red-50 text-red-600"
@click="handleCancelAccount">
📴 注销账号
</button>
<button v-if="isLoggedIn && !isWeChat" class="feature-item hover:bg-red-50 text-red-600"
@click="handleLogout">
退出登录
</button>
</div>
@ -58,23 +66,29 @@
<script setup>
import { storeToRefs } from 'pinia'
import { ref, computed, onBeforeMount } from 'vue'
const router = useRouter()
import headShot from "@/assets/images/head_shot.webp"
import { useAgentStore } from '@/stores/agentStore'
import { useUserStore } from '@/stores/userStore'
import { useEnv } from '@/composables/useEnv'
import useApiFetch from '@/composables/useApiFetch'
const agentStore = useAgentStore()
const userStore = useUserStore()
const { isAgent, level } = storeToRefs(agentStore)
const { userName, userAvatar, isLoggedIn } = storeToRefs(userStore)
const { isWeChat } = useEnv()
const levelNames = {
normal: '普通代理',
'': '普通代理',
VIP: 'VIP代理',
SVIP: 'SVIP代理'
}
const levelText = {
normal: '基础代理特权',
'': '基础代理特权',
VIP: '高级代理特权',
SVIP: '尊享代理特权'
}
@ -82,27 +96,31 @@ const levelText = {
const levelGradient = computed(() => ({
border: {
'normal': 'bg-green-300',
'': 'bg-green-300',
'VIP': 'bg-gradient-to-r from-yellow-400 to-amber-500',
'SVIP': 'bg-gradient-to-r from-purple-400 to-pink-400 shadow-[0_0_15px_rgba(163,51,200,0.2)]'
}[level.value],
badge: {
'normal': 'bg-green-500',
'': 'bg-green-500',
'VIP': 'bg-gradient-to-r from-yellow-500 to-amber-600',
'SVIP': 'bg-gradient-to-r from-purple-500 to-pink-500'
}[level.value],
text: {
'normal': 'text-green-600',
'': 'text-green-600',
'VIP': 'text-amber-600',
'SVIP': 'text-purple-600'
}[level.value]
}))
const maskName = computed(() => {
return (name) => {
return name.substring(0, 3) + "****" + name.substring(7);
}
})
const maskName = (name) => {
if (!name || name.length < 11) return name
return name.substring(0, 3) + "****" + name.substring(7)
}
function toHistory() {
router.push(`/historyQuery`)
}
@ -111,33 +129,97 @@ function toUserAgreement() {
router.push(`/userAgreement`)
}
function toPrivacyPolicy() {
router.push(`/privacyPolicy`) //
}
function toAi() {
router.push(`/ai`) // AI
}
function redirectToLogin() {
router.push(`/login`)
}
function handleLogout() {
//
localStorage.removeItem('token')
localStorage.removeItem('refreshAfter')
localStorage.removeItem('accessExpire')
localStorage.removeItem('userInfo')
localStorage.removeItem('agentInfo')
//
userStore.resetUser()
agentStore.resetAgent()
location.reload()
}
function toService() {
// window.location.href = '/service' //
window.location.href = 'https://work.weixin.qq.com/kfid/kfc5c19b2b93a5e73b9' //
function handleCancelAccount() {
//
if (confirm('注销账号后,您的所有数据将被清除且无法恢复,确定要继续吗?')) {
useApiFetch("/user/cancelOut")
.post()
.json()
.then(({ data, error }) => {
if (!error && data.value && data.value.code === 200) {
alert('账号已注销')
handleLogout()
}
})
.catch(error => {
console.error('注销账号失败:', error)
})
}
}
function toService() {
window.location.href = 'https://work.weixin.qq.com/kfid/kfc8a32720024833f57' //
}
onBeforeMount(() => {
// const token = localStorage.getItem('token') // 使 localStorage token
// if (token) {
// fetchUserInfo()
// agentStore.fetchAgentStatus()
// }
})
const toVipConfig = () => {
router.push({ name: "agentVipConfig" })
}
const getDefaultAvatar = () => {
if (!isAgent.value) return headShot
switch (level.value) {
case 'normal':
case '':
return '/image/shot_nonal.png'
case 'VIP':
return '/image/shot_vip.png'
case 'SVIP':
return '/image/shot_svip.png'
default:
return headShot
}
}
onBeforeMount(() => {
//
const userInfo = localStorage.getItem('userInfo')
if (userInfo) {
try {
const parsedUserInfo = JSON.parse(userInfo)
userStore.updateUserInfo(parsedUserInfo)
} catch (e) {
console.error('解析用户信息失败', e)
}
}
const agentInfo = localStorage.getItem('agentInfo')
if (agentInfo) {
try {
const parsedAgentInfo = JSON.parse(agentInfo)
agentStore.updateAgentInfo(parsedAgentInfo)
} catch (e) {
console.error('解析代理信息失败', e)
}
}
})
</script>
<style scoped>
@ -159,6 +241,11 @@ const toVipConfig = () => {
@apply flex w-full items-center shadow space-x-3 rounded-xl bg-white px-6 py-4 text-left text-gray-700 transition-all duration-300 hover:scale-[1.02] hover:shadow-md focus:outline-none;
}
.feature-item:active {
transform: scale(0.98);
opacity: 0.9;
}
.border-gradient-to-r {
border-image: linear-gradient(to right, var(--tw-gradient-from), var(--tw-gradient-to)) 1;
}

View File

@ -91,13 +91,18 @@ const featureMap = {
CAR061: {
name: '名下车辆',
component: defineAsyncComponent(() => import('@/ui/CCAR061.vue')),
}
},
IDV044: {
name: '婚姻状态',
component: defineAsyncComponent(() => import('@/ui/CIDV044.vue')),
remark: '查询结果为"未婚或尚未登记结婚"时,表示婚姻登记处暂无相关的登记记录。婚姻状态信息由婚姻登记处逐级上报,可能存在数据遗漏或更新滞后。当前可查询的婚姻状态包括:未婚或尚未登记结婚、已婚、离异、离异冷静期。如您对查询结果有疑问,请联系客服反馈。'
},
};
const route = useRoute();
const productId = ref(null);
const isDone = ref(true);
const isDone = ref(false);
const active = ref(null)
const reportData = ref([])
const reportParams = ref({})
@ -107,9 +112,9 @@ const orderId = ref(null);
const orderNo = ref("")
const isEmpty = ref(false)
const isPending = ref(false)
const reportScore = ref(75); //
const reportScore = ref(0); //
onMounted(() => {
onBeforeMount(() => {
const query = new URLSearchParams(window.location.search);
orderNo.value = query.get("out_trade_no");
orderId.value = query.get("order_id");
@ -152,18 +157,18 @@ const getReport = async () => {
} else if (data.value.code === 200002) {
isPending.value = true
}
isDone.value = true
}
}
//
const calculateScore = (reportData) => {
// 0
// 00
let score = 0;
// 90
// 9090
const maxScore = 90;
//
//
const relativeWeights = {
//
'G34BJ03': 250, //
@ -194,7 +199,7 @@ const calculateScore = (reportData) => {
const availableAPIs = reportData.map(item => item.data.apiID).filter(id => relativeWeights[id]);
//
if (availableAPIs.length === 0) return 60; // 60
if (availableAPIs.length === 0) return 30; // 30
//
let totalWeight = 0;
@ -212,7 +217,7 @@ const calculateScore = (reportData) => {
actualWeights[apiID] = relativeWeights[apiID] * pointValue;
});
//
// -
reportData.forEach(item => {
const apiID = item.data.apiID;
const data = item.data.data;
@ -220,7 +225,7 @@ const calculateScore = (reportData) => {
//
if (!actualWeights[apiID]) return;
// API ID
// API ID
switch (apiID) {
case 'G09SC02': //
//
@ -228,61 +233,58 @@ const calculateScore = (reportData) => {
case 'G27BJ05': //
if (data) {
// 0
let noRisk = true;
//
let hasRisk = false;
for (const key in data) {
if (data[key] !== 0 && data[key] !== '0') {
noRisk = false;
if (data[key] !== 0 && data[key] !== '0' &&
key.indexOf('allnum') > -1 &&
!isNaN(parseInt(data[key])) &&
parseInt(data[key]) > 0) {
hasRisk = true;
break;
}
}
if (noRisk || !Object.keys(data).length) {
if (hasRisk) {
score += actualWeights[apiID];
}
} else {
//
score += actualWeights[apiID];
}
break;
case 'G28BJ05': //
if (data) {
// 0
let noRisk = true;
//
let hasRisk = false;
for (const key in data) {
if (data[key] !== 0 && data[key] !== '0') {
noRisk = false;
if (data[key] !== 0 && data[key] !== '0' &&
(key.indexOf('lendamt') > -1 || key.indexOf('num') > -1) &&
!isNaN(parseInt(data[key])) &&
parseInt(data[key]) > 0) {
hasRisk = true;
break;
}
}
if (noRisk || !Object.keys(data).length) {
if (hasRisk) {
score += actualWeights[apiID];
}
} else {
//
score += actualWeights[apiID];
}
break;
case 'G26BJ05': //
if (data) {
// 0
//
const excludeFields = ['swift_number', 'code', 'flag_specialList_c'];
let noRisk = true;
let hasRisk = false;
for (const key in data) {
if (!excludeFields.includes(key) && data[key] !== 0 && data[key] !== '0') {
noRisk = false;
hasRisk = true;
break;
}
}
if (noRisk || !Object.keys(data).length) {
if (hasRisk) {
score += actualWeights[apiID];
}
} else {
//
score += actualWeights[apiID];
}
break;
@ -291,23 +293,20 @@ const calculateScore = (reportData) => {
//
switch (data.risk_level) {
case 'A': //
score += actualWeights[apiID];
//
break;
case 'F': //
score += actualWeights[apiID] * 0.7;
score += actualWeights[apiID] * 0.3;
break;
case 'C': //
case 'D': //
score += actualWeights[apiID] * 0.3;
score += actualWeights[apiID] * 0.7;
break;
case 'B': //
case 'E': //
//
score += actualWeights[apiID];
break;
}
} else {
//
score += actualWeights[apiID];
}
break;
@ -342,12 +341,9 @@ const calculateScore = (reportData) => {
hasRisk = true;
}
if (!hasRisk) {
if (hasRisk) {
score += actualWeights[apiID];
}
} else {
//
score += actualWeights[apiID];
}
break;
@ -356,38 +352,29 @@ const calculateScore = (reportData) => {
// filterType
switch (data.filterType) {
case '0': //
score += actualWeights[apiID];
break;
case '3': //
score += actualWeights[apiID] * 0.7;
break;
case '2': //
score += actualWeights[apiID] * 0.3;
break;
case '1': //
//
break;
}
} else {
//
case '3': //
score += actualWeights[apiID] * 0.3;
break;
case '2': //
score += actualWeights[apiID] * 0.7;
break;
case '1': //
score += actualWeights[apiID];
break;
}
}
break;
case 'G19BJ02': //
if (data && data.is_second_card === false) {
score += actualWeights[apiID];
} else if (!data) {
//
if (data && data.is_second_card === true) {
score += actualWeights[apiID];
}
break;
case 'G02BJ02': //
if (data && data.online_months >= 6) {
score += actualWeights[apiID];
} else if (!data) {
//
if (data && data.online_months < 6) {
score += actualWeights[apiID];
}
break;
@ -396,19 +383,13 @@ const calculateScore = (reportData) => {
case 'G17BJ02': //
case 'KZEYS': //
case 'G20GZ01': //
if (data && data.is_consistent) {
score += actualWeights[apiID];
} else if (!data) {
//
if (data && data.is_consistent === false) {
score += actualWeights[apiID];
}
break;
case 'FIN019': //
if (data && data.is_blacklisted === false) {
score += actualWeights[apiID];
} else if (!data) {
//
if (data && data.is_blacklisted === true) {
score += actualWeights[apiID];
}
break;
@ -603,7 +584,7 @@ const maskValue = computed(() => {
<div class="text-sm text-gray-600">身份证信息核验通过</div>
</div>
</div>
<div class="flex items-center bg-blue-100 rounded-xl px-4 py-2 flex-1">
<!-- <div class="flex items-center bg-blue-100 rounded-xl px-4 py-2 flex-1">
<div
class="bg-green-500 w-12 h-12 text-white text-xl flex items-center justify-center rounded-full mr-4">
</div>
@ -612,7 +593,7 @@ const maskValue = computed(() => {
<div class="text-sm text-gray-600">被查询人姓名与运营商提供的一致</div>
<div class="text-sm text-gray-600">被查询人身份证与运营商提供的一致</div>
</div>
</div>
</div> -->
</div>
</div>
@ -627,11 +608,11 @@ const maskValue = computed(() => {
<van-tab v-for="(item, index) in reportData" :key="index"
:title="featureMap[item.data.apiID]?.name">
<div id="lawsuit" class="title mb-4">{{ featureMap[item.data.apiID]?.name }}</div>
<component :is="featureMap[item.data.apiID].component" :data="item.data.data"
<component :is="featureMap[item.data.apiID]?.component" :data="item.data.data"
:params="reportParams">
</component>
<LRemark v-if="featureMap[item.data.apiID].remark"
:content="featureMap[item.data.apiID].remark" />
<LRemark v-if="featureMap[item.data.apiID]?.remark"
:content="featureMap[item.data.apiID]?.remark" />
</van-tab>
<div class="card">
<div>

View File

@ -9,7 +9,6 @@
<script setup>
onMounted(() => {
//
(function (d, t) {
const BASE_URL = "https://service.quannengcha.com";
const g = d.createElement(t),

View File

@ -1,5 +1,9 @@
<script setup>
const router = useRouter()
import { storeToRefs } from 'pinia';
const agentStore = useAgentStore()
const { isAgent } = storeToRefs(agentStore)
import indexIcon1 from '@/assets/images/index_icon_1.png'
import indexIcon2 from '@/assets/images/index_icon_2.png'
import indexIcon3 from '@/assets/images/index_icon_3.png'
@ -17,6 +21,9 @@ function toInvitation() {
const toPromote = () => {
router.push({ name: "promote" })
}
function toAgentApply() {
router.push({ name: "invitationAgentApplySelf" })
}
const toHelp = () => {
router.push("/help")
}
@ -110,13 +117,13 @@ function toHistory() {
</div>
<div class="text-center mt-1 font-bold">邀请下级</div>
</div>
<!-- <div class="" @click="toHelp">
<div class="" @click="toHelp">
<div
class="h-16 w-16 p-2 bg-gradient-to-b from-white to-blue-100/10 rounded-full shadow-lg flex items-center justify-center">
<img src="@/assets/images/icon_bz.svg" alt="帮助中心" class="w-12 h-12" />
</div>
<div class="text-center mt-1 font-bold">帮助中心</div>
</div> -->
</div>
<div class="" @click="toHistory">
<div
class="h-16 w-16 p-2 bg-gradient-to-b from-white to-blue-100/10 rounded-full shadow-lg flex items-center justify-center">
@ -151,6 +158,9 @@ function toHistory() {
</div>
</template>
</div>
<div v-if="!isAgent" class="mt-4 rounded-2xl overflow-hidden" @click="toAgentApply">
<img src="@/assets/images/index_b_banner.png" class="w-full h-full" mode="widthFix" />
</div>
<div class="mt-4 box-border h-14 w-full flex items-center rounded-xl bg-white px-4 text-gray-700 shadow-xl"
@click="toHistory">
<img class="mr-4 h-10 w-10" src="@/assets/images/bg_icon.png" mode="widthFix" />