diff --git a/src/assets/images/car_banner.png b/src/assets/images/car_banner.png new file mode 100644 index 0000000..02d27e2 Binary files /dev/null and b/src/assets/images/car_banner.png differ diff --git a/src/assets/images/category/clcp.svg b/src/assets/images/category/clcp.svg new file mode 100644 index 0000000..6780d4f --- /dev/null +++ b/src/assets/images/category/clcp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/category/clcx.svg b/src/assets/images/category/clcx.svg new file mode 100644 index 0000000..6512a7d --- /dev/null +++ b/src/assets/images/category/clcx.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/category/clxx.svg b/src/assets/images/category/clxx.svg new file mode 100644 index 0000000..f99a9c2 --- /dev/null +++ b/src/assets/images/category/clxx.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/category/cxcl.svg b/src/assets/images/category/cxcl.svg new file mode 100644 index 0000000..dbfc64f --- /dev/null +++ b/src/assets/images/category/cxcl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/category/esc.svg b/src/assets/images/category/esc.svg new file mode 100644 index 0000000..aa81bcc --- /dev/null +++ b/src/assets/images/category/esc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/category/escgz.svg b/src/assets/images/category/escgz.svg new file mode 100644 index 0000000..e97855c --- /dev/null +++ b/src/assets/images/category/escgz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/category/hygj.svg b/src/assets/images/category/hygj.svg new file mode 100644 index 0000000..e29ef73 --- /dev/null +++ b/src/assets/images/category/hygj.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/category/icon_vehicle_risk.svg b/src/assets/images/category/icon_vehicle_risk.svg new file mode 100644 index 0000000..27295fa --- /dev/null +++ b/src/assets/images/category/icon_vehicle_risk.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + diff --git a/src/assets/images/category/icon_vehicle_search.svg b/src/assets/images/category/icon_vehicle_search.svg new file mode 100644 index 0000000..89bd8cd --- /dev/null +++ b/src/assets/images/category/icon_vehicle_search.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + diff --git a/src/assets/images/category/icon_vehicle_value.svg b/src/assets/images/category/icon_vehicle_value.svg new file mode 100644 index 0000000..e701255 --- /dev/null +++ b/src/assets/images/category/icon_vehicle_value.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + diff --git a/src/assets/images/category/icon_verify_bank.svg b/src/assets/images/category/icon_verify_bank.svg new file mode 100644 index 0000000..194512c --- /dev/null +++ b/src/assets/images/category/icon_verify_bank.svg @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/src/assets/images/category/icon_verify_company.svg b/src/assets/images/category/icon_verify_company.svg new file mode 100644 index 0000000..62c08d5 --- /dev/null +++ b/src/assets/images/category/icon_verify_company.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/src/assets/images/category/icon_verify_id.svg b/src/assets/images/category/icon_verify_id.svg new file mode 100644 index 0000000..65e8335 --- /dev/null +++ b/src/assets/images/category/icon_verify_id.svg @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/src/assets/images/category/icon_verify_operator.svg b/src/assets/images/category/icon_verify_operator.svg new file mode 100644 index 0000000..838f2e8 --- /dev/null +++ b/src/assets/images/category/icon_verify_operator.svg @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/src/assets/images/category/icon_verify_score.svg b/src/assets/images/category/icon_verify_score.svg new file mode 100644 index 0000000..7f233aa --- /dev/null +++ b/src/assets/images/category/icon_verify_score.svg @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/src/assets/images/category/rchyjb.svg b/src/assets/images/category/rchyjb.svg new file mode 100644 index 0000000..27a9cdc --- /dev/null +++ b/src/assets/images/category/rchyjb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/category/rchyxb.svg b/src/assets/images/category/rchyxb.svg new file mode 100644 index 0000000..30b0561 --- /dev/null +++ b/src/assets/images/category/rchyxb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/fxpg_banner.png b/src/assets/images/fxpg_banner.png new file mode 100644 index 0000000..b21698e Binary files /dev/null and b/src/assets/images/fxpg_banner.png differ diff --git a/src/assets/images/hygj.svg b/src/assets/images/hygj.svg new file mode 100644 index 0000000..e29ef73 --- /dev/null +++ b/src/assets/images/hygj.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/hygj_banner.png b/src/assets/images/hygj_banner.png new file mode 100644 index 0000000..7f725f2 Binary files /dev/null and b/src/assets/images/hygj_banner.png differ diff --git a/src/components/BaseReport.vue b/src/components/BaseReport.vue index 261b8b2..f94ee57 100644 --- a/src/components/BaseReport.vue +++ b/src/components/BaseReport.vue @@ -268,6 +268,11 @@ const featureMap = { name: "违约失信", component: defineAsyncComponent(() => import("@/ui/CFLXG3D56.vue")), }, + FLXG3A9B: { + name: "限高被执行人", + component: defineAsyncComponent(() => import("@/ui/CFLX3A9B.vue")), + remark: '限高被执行人模块展示法院公布的限制高消费记录,并同时提示历史失信记录,帮助识别严重履约风险。' + }, FLXG7E8F: { name: "司法涉诉", component: defineAsyncComponent(() => @@ -288,6 +293,16 @@ const featureMap = { ), remark: '人企关系加强版提供全面的企业关联分析,包括投资企业记录、高管任职记录和涉诉风险等多维度信息。' }, + QYGL66SL: { + name: "企业司法涉诉", + component: defineAsyncComponent(() => import("@/ui/CQYGL66SL.vue")), + remark: '企业司法涉诉模块展示被查询企业在全国法院公开信息中的民事案件情况,包括案件数量、结案情况、涉案地域与案由分布等,用于评估企业的司法风险。' + }, + QYGL2S0W: { + name: "失信被执行人", + component: defineAsyncComponent(() => import("@/ui/CQYGL2S0W.vue")), + remark: '失信被执行人模块展示最高法院公布的失信记录,包括履行情况、执行法院、执行依据等信息,是评估严重违约风险的重要参考。' + }, // 人企关系加强版拆分模块 CQYGL3F8E_Investment: { name: "投资企业记录", @@ -329,6 +344,44 @@ const featureMap = { name: "名下车辆", component: defineAsyncComponent(() => import("@/ui/CQCXG9P1C.vue")), }, + QCXGGB2Q: { + name: "人车核验简版", + component: defineAsyncComponent(() => import("@/ui/CQCXGGB2Q.vue")), + }, + QCXGYTS2: { + name: "人车核验详版", + component: defineAsyncComponent(() => import("@/ui/CQCXGYTS2.vue")), + }, + QCXG5F3A: { + name: "名下车辆(车牌)", + component: defineAsyncComponent(() => import("@/ui/QCXG5F3A.vue")), + }, + QCXG4D2E: { name: "名下车辆(数量)", component: defineAsyncComponent(() => import("@/ui/CQCXG4D2E.vue")) }, + QCXG5U0Z: { name: "车辆静态信息查询", component: defineAsyncComponent(() => import("@/ui/CQCXG5U0Z.vue")) }, + QCXG1U4U: { name: "车辆里程记录(混合查询)", component: defineAsyncComponent(() => import("@/ui/CQCXG1U4U.vue")) }, + QCXGY7F2: { name: "二手车VIN估值", component: defineAsyncComponent(() => import("@/ui/CQCXGY7F2.vue")) }, + QCXG1H7Y: { name: "车辆过户简版查询", component: defineAsyncComponent(() => import("@/ui/CQCXG1H7Y.vue")) }, + QCXG4I1Z: { name: "车辆过户详版查询", component: defineAsyncComponent(() => import("@/ui/CQCXG4I1Z.vue")) }, + QCXG3Y6B: { name: "车辆维保简版查询", component: defineAsyncComponent(() => import("@/ui/CQCXG3Y6B.vue")) }, + QCXG3Z3L: { name: "车辆维保详细版查询", component: defineAsyncComponent(() => import("@/ui/CQCXG3Z3L.vue")) }, + QCXGP00W: { name: "车辆出险详版查询", component: defineAsyncComponent(() => import("@/ui/CQCXGP00W.vue")) }, + QCXG6B4E: { name: "车辆出险记录核验", component: defineAsyncComponent(() => import("@/ui/CQCXG6B4E.vue")) }, + IVYZ9K7F: { name: "公安二要素认证", component: defineAsyncComponent(() => import("@/ui/CIVYZ9K7F.vue")) }, + IVYZA1B3: { name: "公安三要素", component: defineAsyncComponent(() => import("@/ui/CIVYZA1B3.vue")) }, + IVYZ6M8P: { name: "职业资格证书查询", component: defineAsyncComponent(() => import("@/ui/CIVYZ6M8P.vue")) }, + JRZQ8B3C: { name: "个人消费能力等级", component: defineAsyncComponent(() => import("@/ui/JRZQ8B3C/index.vue")) }, + YYSY3M8S: { name: "运营商二要素", component: defineAsyncComponent(() => import("@/ui/CYYSY3M8S.vue")) }, + YYSYK9R4: { name: "全网手机三要素验证周更", component: defineAsyncComponent(() => import("@/ui/CYYSYK9R4.vue")) }, + YYSYF2T7: { name: "号码二次放号", component: defineAsyncComponent(() => import("@/ui/CYYSYF2T7.vue")) }, + YYSYK8R3: { name: "手机空号检测", component: defineAsyncComponent(() => import("@/ui/CYYSYK8R3.vue")) }, + YYSYS9W1: { name: "手机携号转网", component: defineAsyncComponent(() => import("@/ui/CYYSYS9W1.vue")) }, + YYSYE7V5: { name: "手机在网状态", component: defineAsyncComponent(() => import("@/ui/CYYSYE7V5.vue")) }, + YYSYP0T4: { name: "手机号码在网时长", component: defineAsyncComponent(() => import("@/ui/CYYSYP0T4.vue")) }, + YYSY6F2B: { name: "手机消费区间验证", component: defineAsyncComponent(() => import("@/ui/CYYSY6F2B.vue")) }, + YYSY9E4A: { name: "手机号码归属地核验", component: defineAsyncComponent(() => import("@/ui/CYYSY9E4A.vue")) }, + QYGL5F6A: { name: "名下企业关联", component: defineAsyncComponent(() => import("@/ui/CQYGL5F6A.vue")) }, + JRZQACAB: { name: "银行卡四要素验证(详版)", component: defineAsyncComponent(() => import("@/ui/CJRZQACAB.vue")) }, + JRZQ0B6Y: { name: "银行卡黑名单", component: defineAsyncComponent(() => import("@/ui/CJRZQ0B6Y.vue")) }, BehaviorRiskScan: { name: "风险行为扫描", component: defineAsyncComponent(() => @@ -595,13 +648,22 @@ const featureRiskLevels = { // 🟡 中风险类 - 权重 5 'QYGL3F8E': 5, // 人企关系加强版 'QCXG7A2B': 5, // 名下车辆 + 'QCXGGB2Q': 5, // 人车核验简版 + 'QCXGYTS2': 5, // 人车核验详版 + 'QCXG5F3A': 5, // 名下车辆(车牌) + 'QCXG4D2E': 5, 'QCXG5U0Z': 5, 'QCXG1U4U': 5, 'QCXGY7F2': 5, 'QCXG1H7Y': 5, + 'QCXG4I1Z': 5, 'QCXG3Y6B': 5, 'QCXG3Z3L': 5, 'QCXGP00W': 5, 'QCXG6B4E': 5, 'JRZQ09J8': 5, // 收入评估 + 'IVYZ9K7F': 5, 'IVYZA1B3': 5, 'IVYZ6M8P': 5, 'JRZQ8B3C': 3, + 'YYSY3M8S': 5, 'YYSYK9R4': 5, 'YYSYF2T7': 5, 'YYSYK8R3': 5, + 'YYSYS9W1': 5, 'YYSYE7V5': 5, 'YYSYP0T4': 5, 'YYSY6F2B': 5, + 'YYSY9E4A': 3, 'QYGL5F6A': 5, 'JRZQACAB': 5, 'JRZQ0B6Y': 5, + 'QYGL66SL': 10, 'QYGL2S0W': 10, 'FLXG3A9B': 10, // 🔵 低风险类 - 权重 3 'IVYZ5733': 3, // 婚姻状态 'IVYZ9A2B': 3, // 学历信息 'IVYZ3P9M': 3, // 学历信息查询(实时版) - 'JRZQ8B3C': 3, // 个人消费能力 // 📊 复合报告类 - 按子模块动态计算 'DWBG8B4D': 0, // 谛听多维报告(由子模块计算) diff --git a/src/components/InquireForm.vue b/src/components/InquireForm.vue index 8c87f40..4121d6d 100644 --- a/src/components/InquireForm.vue +++ b/src/components/InquireForm.vue @@ -1,15 +1,13 @@ @@ -752,19 +1163,11 @@ button:active { transform: translateY(0); } -/* 梯形背景图片样式 */ -.trapezoid-bg-image { - background-size: contain; - background-repeat: no-repeat; - background-position: center; - height: 44px; -} - /* 卡片容器样式 */ .card-container { background: white; border-radius: 8px; - padding: 32px 16px; + padding: 16px; box-shadow: 0px 0px 24px 0px #3F3F3F0F; } @@ -792,4 +1195,58 @@ button:active { border-radius: 50%; margin-right: 8px; } + +/* 行驶证形状上传框 */ +.vlphoto-frame { + width: 100%; + max-width: 320px; + aspect-ratio: 1.55; + margin: 0 auto; + border-radius: 14px; + border: 2px dashed #c9c9c9; + background: linear-gradient(145deg, #f8f9fa 0%, #eef0f2 100%); + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; + cursor: pointer; + transition: border-color 0.2s, background 0.2s; + outline: none; +} + +.vlphoto-frame:hover { + border-color: var(--color-primary, #2563eb); + background: linear-gradient(145deg, #f0f4ff 0%, #e8eeff 100%); +} + +.vlphoto-frame:focus-visible { + border-color: var(--color-primary, #2563eb); + box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2); +} + +.vlphoto-preview { + width: 100%; + height: 100%; + object-fit: cover; + display: block; +} + +.vlphoto-placeholder { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 8px; + color: #9ca3af; +} + +.vlphoto-icon { + font-size: 2.5rem; + line-height: 1; +} + +.vlphoto-hint { + font-size: 14px; + color: #6b7280; +} \ No newline at end of file diff --git a/src/composables/useInquireForm.js b/src/composables/useInquireForm.js new file mode 100644 index 0000000..52e0276 --- /dev/null +++ b/src/composables/useInquireForm.js @@ -0,0 +1,291 @@ +import { reactive, computed } from "vue"; + +/** + * 通用查询表单字段与规则(可按 feature 扩展) + * + * 目标: + * - 统一管理「这个产品需要哪些输入控件」 + * - 暴露统一的 formData / 校验规则 / 字段可见性 / 组装请求体 + * + * 使用方式(示例,见 InquireForm.vue): + * const { formData, isPhoneNumberValid, isIdCardValid, isHasInput, buildRequestPayload } = + * useInquireForm(feature); + */ +export function useInquireForm(featureRef) { + // 1. 表单字段全集(后续有新字段,只在这里统一扩展) + const formData = reactive({ + name: "", + idCard: "", + mobile: "", + verificationCode: "", + // 预留扩展字段位(婚姻、车辆、企业等) + nameMan: "", + idCardMan: "", + nameWoman: "", + idCardWoman: "", + entName: "", + entCode: "", + carLicense: "", + carType: "", + vinCode: "", + certificateNumber: "", + // 车辆类扩展(仅必填项) + userType: "1", + returnUrl: "", + imageUrl: "", + vehicleLocation: "", + firstRegistrationDate: "", + vlphotoData: "", + authorized: "1", + // 核验工具 + bankCard: "", + photoData: "", + // 协议 + agreeToTerms: false, + }); + + // 2. 默认输入字段(大部分个人产品共用) + const defaultInput = ["name", "idCard", "mobile", "verificationCode"]; + + /** + * 3. 不同产品的专用字段配置 + * key 为 feature(route 参数 / 产品英文编码) + * value 为该产品需要的字段数组 + * + * 先以你当前主要产品为例填入,后续有新产品直接在这里扩展即可。 + */ + const productFieldConfig = { + // 婚恋风险(当前与默认字段一致,单独配置方便以后扩展) + marriage: ["name", "idCard", "mobile", "verificationCode"], + + // 司法涉诉 + toc_PersonalLawsuit: ["name", "idCard", "mobile", "verificationCode"], + // 人企关系加强版:仅身份证号 + toc_PersonEnterprisePro: ["idCard"], + // 新企业司法涉诉(QYGL66SL):仅企业名称,其他字段后端自动补齐 + toc_EnterpriseLawsuitQYGL66SL: ["entName"], + + // 被执行人 / 限高 + // 限高被执行人 FLXG3A9B:姓名 + 身份证 + 手机号(授权由后端默认传 1,前端不展示) + toc_LimitHighExecuted: ["name", "idCard", "mobile"], + // 失信被执行人 QYGL2S0W:姓名 + 身份证;type 后端默认 per + toc_DishonestExecutedPerson: ["name", "idCard"], + + // 婚姻状况系列(占位,后续可根据实际字段调整) + toc_PersonalMarriageStatus: [ + "name", + "idCard", + "mobile", + "verificationCode", + ], + toc_MarriageStatusRegisterTime: [ + "name", + "idCard", + "mobile", + "verificationCode", + ], + toc_MarriageStatusSupplement: [ + "name", + "idCard", + "mobile", + "verificationCode", + ], + toc_MarriageStatusVerify: [ + "name", + "idCard", + "mobile", + "verificationCode", + ], + toc_DualMarriageStatusRegisterTime: [ + "nameMan", + "idCardMan", + "nameWoman", + "idCardWoman", + "mobile", + "verificationCode", + ], + + // 车辆相关(占位,后续可细化) + toc_VehiclesUnderName: ["name", "idCard", "mobile", "verificationCode"], + // 名下车辆(车牌):姓名 + 身份证 + 手机 + 验证码 + toc_VehiclesUnderNamePlate: [ + "name", + "idCard", + "mobile", + "verificationCode", + ], + // 人车核验简版:姓名 + 号牌类型 + 车牌号 + toc_PersonVehicleVerification: ["name", "carType", "carLicense"], + // 人车核验详版:姓名 + 号牌类型 + 车牌号(同简版) + toc_PersonVehicleVerificationDetail: ["name", "carType", "carLicense"], + // 名下车辆(数量) QCXG4D2E:仅 user_type + id_card + toc_VehiclesUnderNameCount: ["userType", "idCard"], + // 车辆静态信息 QCXG5U0Z:仅 vin_code(车辆类不要求手机号与验证码) + toc_VehicleStaticInfo: ["vinCode"], + // 车辆里程混合 QCXG1U4U(仅必填:vin_code, image_url;回调地址由后端自动生成) + toc_VehicleMileageMixed: ["vinCode", "imageUrl"], + // 二手车VIN估值 QCXGY7F2(仅必填:vin_code, vehicle_location, first_registrationdate) + toc_VehicleVinValuation: [ + "vinCode", + "vehicleLocation", + "firstRegistrationDate", + ], + // 车辆过户简版 QCXG1H7Y(必填:vin_code + 车牌号) + toc_VehicleTransferSimple: ["vinCode", "carLicense"], + // 车辆过户详版 QCXG4I1Z + toc_VehicleTransferDetail: ["vinCode"], + // 车辆维保简版 QCXG3Y6B(仅必填:vin_code;回调地址由后端自动生成) + toc_VehicleMaintenanceSimple: ["vinCode"], + // 车辆维保详细版 QCXG3Z3L(仅必填:vin_code;回调地址由后端自动生成) + toc_VehicleMaintenanceDetail: ["vinCode"], + // 车辆出险详版 QCXGP00W(仅必填:vin_code, vlphoto_data;回调地址由后端自动生成) + toc_VehicleClaimDetail: ["vinCode", "vlphotoData"], + // 车辆出险记录核验 QCXG6B4E(授权由后端默认传 1,前端不展示) + toc_VehicleClaimVerify: ["vinCode"], + + // 核验工具(verify feature.md) + toc_PoliceTwoFactors: ["mobile", "idCard", "name"], + toc_PoliceThreeFactors: ["photoData", "idCard", "name"], + toc_ProfessionalCertificate: ["idCard", "name"], + toc_PersonalConsumptionCapacityLevel: ["mobile", "idCard", "name"], // 个人消费能力(沿用现有 product_en) + toc_OperatorTwoFactors: ["mobile", "name"], + toc_MobileThreeFactors: ["mobile", "idCard", "name"], + toc_NumberRecycle: ["mobile"], + toc_MobileEmptyCheck: ["mobile"], + toc_MobilePortability: ["mobile"], + toc_MobileOnlineStatus: ["mobile"], + toc_MobileOnlineDuration: ["mobile"], + toc_MobileAttribution: ["mobile"], + toc_MobileConsumptionRange: ["mobile", "authorized"], + toc_EnterpriseRelation: ["idCard"], + toc_BankcardFourFactors: ["mobile", "idCard", "bankCard", "name"], + toc_BankcardBlacklist: ["mobile", "idCard", "name", "bankCard"], + }; + + // 当前 feature 名称 + const currentFeature = computed(() => featureRef?.value || featureRef); + + /** + * 4. 判断某个字段在当前产品下是否需要显示 / 校验 / 组包 + */ + const isHasInput = (field) => { + const key = currentFeature.value; + if (key && productFieldConfig[key]) { + return productFieldConfig[key].includes(field); + } + return defaultInput.includes(field); + }; + + // 5. 通用校验规则(不直接弹 Toast,只返回布尔值,UI 再决定提示) + const isPhoneNumberValid = computed(() => { + if (!formData.mobile) return false; + return /^1[3-9]\d{9}$/.test(formData.mobile); + }); + + const isIdCardValid = computed(() => { + if (!formData.idCard) return false; + return /^\d{17}[\dX]$/i.test(formData.idCard); + }); + + // 预留:其他字段校验(如车牌、车架号等)后续可加在这里 + + /** + * 6. 根据当前产品配置组装请求体 + * 仅包含当前产品需要的字段;字段名与后端约定对齐。 + */ + const buildRequestPayload = () => { + const req = {}; + + if (isHasInput("name") && formData.name) { + req.name = formData.name; + } + if (isHasInput("idCard") && formData.idCard) { + req.id_card = formData.idCard; + } + if (isHasInput("mobile") && formData.mobile) { + req.mobile = formData.mobile; + } + if (isHasInput("verificationCode") && formData.verificationCode) { + req.code = formData.verificationCode; + } + + // 预留字段映射(以后启用时直接在这里补充) + if (isHasInput("nameMan") && formData.nameMan) { + req.name_man = formData.nameMan; + } + if (isHasInput("idCardMan") && formData.idCardMan) { + req.id_card_man = formData.idCardMan; + } + if (isHasInput("nameWoman") && formData.nameWoman) { + req.name_woman = formData.nameWoman; + } + if (isHasInput("idCardWoman") && formData.idCardWoman) { + req.id_card_woman = formData.idCardWoman; + } + if (isHasInput("entName") && formData.entName) { + req.ent_name = formData.entName; + } + if (isHasInput("entCode") && formData.entCode) { + req.ent_code = formData.entCode; + } + if (isHasInput("carLicense") && formData.carLicense) { + req.car_license = formData.carLicense.trim(); + } + if (isHasInput("carType") && formData.carType) { + req.car_type = formData.carType; + } + if (isHasInput("vinCode") && formData.vinCode) { + req.vin_code = formData.vinCode.trim(); + } + if (isHasInput("certificateNumber") && formData.certificateNumber) { + req.certificate_number = formData.certificateNumber; + } + // 车辆类扩展字段(与后端 types/query.go 对齐) + if (isHasInput("userType") && formData.userType) { + req.user_type = formData.userType; + } + if (isHasInput("returnUrl") && formData.returnUrl) { + req.return_url = formData.returnUrl.trim(); + } + if (isHasInput("imageUrl") && formData.imageUrl) { + req.image_url = formData.imageUrl.trim(); + } + if (isHasInput("vehicleLocation") && formData.vehicleLocation) { + req.vehicle_location = formData.vehicleLocation.trim(); + } + if ( + isHasInput("firstRegistrationDate") && + formData.firstRegistrationDate + ) { + req.first_registrationdate = formData.firstRegistrationDate.trim(); + } + if (isHasInput("vlphotoData") && formData.vlphotoData) { + req.vlphoto_data = formData.vlphotoData; + } + if ( + isHasInput("authorized") && + formData.authorized !== undefined && + formData.authorized !== "" + ) { + req.authorized = String(formData.authorized); + } + if (isHasInput("bankCard") && formData.bankCard) { + req.bank_card = formData.bankCard.trim(); + } + if (isHasInput("photoData") && formData.photoData) { + req.photo_data = formData.photoData; + } + + return req; + }; + + return { + formData, + isPhoneNumberValid, + isIdCardValid, + isHasInput, + buildRequestPayload, + defaultInput, + productFieldConfig, + }; +} diff --git a/src/config/inquireCategories.js b/src/config/inquireCategories.js new file mode 100644 index 0000000..f5da1ab --- /dev/null +++ b/src/config/inquireCategories.js @@ -0,0 +1,346 @@ +/** + * 查询模块二级分类配置 + * 首页点击模块后进入的方格列表选项,每个选项对应一个查询类型(feature) + * banner: 该大类顶部海报图(assets/images 下文件名) + */ +export const inquireCategoryConfig = { + /** 司法涉诉 */ + lawsuit: { + title: "司法涉诉", + banner: "fxpg_banner.png", + items: [ + { + name: "个人司法涉诉", + feature: "toc_PersonalLawsuit", + desc: "民事、刑事、行政、执行、失信、限高等", + icon: "grss_icon.svg", + iconFrom: "category", + }, + { + name: "企业司法涉诉", + feature: "toc_EnterpriseLawsuitQYGL66SL", + desc: "企业涉诉与执行信息", + icon: "qyss_icon.svg", + iconFrom: "category", + }, + { + name: "人企关系加强版", + feature: "toc_PersonEnterprisePro", + desc: "仅身份证号", + icon: "renqiguanxi.svg", + iconFrom: "category", + }, + { + name: "限高被执行人", + feature: "toc_LimitHighExecuted", + desc: "限制高消费被执行人信息", + icon: "xianzhigaoxiaofei.svg", + iconFrom: "category", + }, + { + name: "失信被执行人", + feature: "toc_DishonestExecutedPerson", + desc: "失信被执行人信息", + icon: "sjsys_icon.svg", + iconFrom: "category", + }, + ], + }, + /** 婚恋风险 */ + marriage: { + title: "婚恋风险", + banner: "hygj_banner.png", + items: [ + { + name: "婚恋风险评估", + feature: "marriage", + desc: "多维度婚恋对象风险分析", + icon: "renqiguanxi.svg", + }, + ], + }, + /** 车辆查询 */ + vehicle: { + title: "车辆查询", + banner: "car_banner.png", + items: [ + { + name: "名下车辆查询", + feature: "toc_VehiclesUnderName", + desc: "个人名下车辆信息", + icon: "mxcl_icon.svg", + iconFrom: "category", + }, + { + name: "人车核验(简版)", + feature: "toc_PersonVehicleVerification", + desc: "根据车牌与号牌类型核验车辆与人员是否匹配", + icon: "rchyjb.svg", + iconFrom: "category", + }, + { + name: "人车核验(详版)", + feature: "toc_PersonVehicleVerificationDetail", + desc: "提供更丰富的人车匹配详细信息", + icon: "rchyxb.svg", + iconFrom: "category", + }, + { + name: "名下车辆(车牌)", + feature: "toc_VehiclesUnderNamePlate", + desc: "按身份证与姓名查询名下车辆信息", + icon: "mxcl_icon.svg", + iconFrom: "category", + }, + { + name: "名下车辆(数量)", + feature: "toc_VehiclesUnderNameCount", + desc: "查询名下车辆数量", + icon: "mxcl_icon.svg", + iconFrom: "category", + }, + { + name: "车辆静态信息查询", + feature: "toc_VehicleStaticInfo", + desc: "车辆静态信息", + icon: "clxx.svg", + iconFrom: "category", + }, + { + name: "车辆里程记录(混合查询)", + feature: "toc_VehicleMileageMixed", + desc: "车辆里程混合查询", + icon: "clcx.svg", + iconFrom: "category", + }, + { + name: "二手车VIN估值", + feature: "toc_VehicleVinValuation", + desc: "按VIN查询二手车估值", + icon: "escgz.svg", + iconFrom: "category", + }, + { + name: "车辆过户简版查询", + feature: "toc_VehicleTransferSimple", + desc: "车辆过户简版", + icon: "esc.svg", + iconFrom: "category", + }, + { + name: "车辆过户详版查询", + feature: "toc_VehicleTransferDetail", + desc: "车辆过户详版", + icon: "esc.svg", + iconFrom: "category", + }, + { + name: "车辆维保简版查询", + feature: "toc_VehicleMaintenanceSimple", + desc: "车辆维保简版", + icon: "clxx.svg", + iconFrom: "category", + }, + { + name: "车辆维保详细版查询", + feature: "toc_VehicleMaintenanceDetail", + desc: "车辆维保详细版", + icon: "clxx.svg", + iconFrom: "category", + }, + { + name: "车辆出险详版查询", + feature: "toc_VehicleClaimDetail", + desc: "车辆出险详版", + icon: "cxcl.svg", + iconFrom: "category", + }, + { + name: "车辆出险记录核验", + feature: "toc_VehicleClaimVerify", + desc: "车辆出险记录核验", + icon: "cxcl.svg", + iconFrom: "category", + }, + ], + }, + /** 核验工具 */ + verify: { + title: "核验工具", + banner: "hygj_banner.png", + items: [ + { + name: "公安二要素认证", + feature: "toc_PoliceTwoFactors", + desc: "手机号+身份证+姓名", + icon: "icon_verify_id.svg", + iconFrom: "category", + }, + { + name: "公安三要素", + feature: "toc_PoliceThreeFactors", + desc: "人像图+身份证+姓名", + icon: "icon_verify_id.svg", + iconFrom: "category", + }, + { + name: "职业资格证书查询", + feature: "toc_ProfessionalCertificate", + desc: "身份证+姓名", + icon: "icon_verify_id.svg", + iconFrom: "category", + }, + { + name: "个人消费能力等级", + feature: "toc_PersonalConsumptionCapacityLevel", + desc: "手机号+身份证+姓名", + icon: "icon_verify_score.svg", + iconFrom: "category", + }, + { + name: "运营商二要素", + feature: "toc_OperatorTwoFactors", + desc: "手机号+姓名", + icon: "icon_verify_operator.svg", + iconFrom: "category", + }, + { + name: "全网手机三要素验证周更", + feature: "toc_MobileThreeFactors", + desc: "手机号+身份证+姓名", + icon: "icon_verify_operator.svg", + iconFrom: "category", + }, + { + name: "号码二次放号", + feature: "toc_NumberRecycle", + desc: "手机号", + icon: "icon_verify_operator.svg", + iconFrom: "category", + }, + { + name: "手机空号检测", + feature: "toc_MobileEmptyCheck", + desc: "手机号", + icon: "icon_verify_operator.svg", + iconFrom: "category", + }, + { + name: "手机携号转网", + feature: "toc_MobilePortability", + desc: "手机号", + icon: "icon_verify_operator.svg", + iconFrom: "category", + }, + { + name: "手机在网状态", + feature: "toc_MobileOnlineStatus", + desc: "手机号", + icon: "icon_verify_operator.svg", + iconFrom: "category", + }, + { + name: "手机号码在网时长", + feature: "toc_MobileOnlineDuration", + desc: "手机号", + icon: "icon_verify_operator.svg", + iconFrom: "category", + }, + { + name: "手机消费区间验证", + feature: "toc_MobileConsumptionRange", + desc: "手机号+授权", + icon: "icon_verify_operator.svg", + iconFrom: "category", + }, + { + name: "手机号码归属地核验", + feature: "toc_MobileAttribution", + desc: "手机号", + icon: "icon_verify_operator.svg", + iconFrom: "category", + }, + { + name: "名下企业关联", + feature: "toc_EnterpriseRelation", + desc: "法人身份证(选填)", + icon: "icon_verify_company.svg", + iconFrom: "category", + }, + { + name: "人企关系加强版", + feature: "toc_PersonEnterprisePro", + desc: "仅身份证号", + icon: "icon_verify_company.svg", + iconFrom: "category", + }, + { + name: "银行卡四要素验证(详版)", + feature: "toc_BankcardFourFactors", + desc: "手机+身份证+银行卡+姓名", + icon: "icon_verify_bank.svg", + iconFrom: "category", + }, + { + name: "银行卡黑名单(实时)", + feature: "toc_BankcardBlacklist", + desc: "手机+身份证+姓名+银行卡", + icon: "icon_verify_bank.svg", + iconFrom: "category", + }, + ], + }, + /** 婚姻状况 */ + marriageStatus: { + title: "婚姻状况", + banner: "hygj_banner.png", + items: [ + { + name: "个人婚姻状态", + feature: "toc_PersonalMarriageStatus", + desc: "个人婚姻登记状态", + icon: "zrrsczt_icon.svg", + iconFrom: "category", + }, + // { + // name: '婚姻状态查询(登记时间版)', + // feature: 'toc_MarriageStatusRegisterTime', + // desc: '按登记时间查询婚姻状态', + // icon: 'zrrsczt_icon.svg', + // iconFrom: 'category', + // }, + // { + // name: '婚姻状态查询(补证版)', + // feature: 'toc_MarriageStatusSupplement', + // desc: '补证版婚姻状态查询', + // icon: 'zrrsczt_icon.svg', + // iconFrom: 'category', + // }, + // { + // name: '婚姻状态核验', + // feature: 'toc_MarriageStatusVerify', + // desc: '婚姻状态核验', + // icon: 'zrrsczt_icon.svg', + // iconFrom: 'category', + // }, + // { + // name: '双人婚姻状态(登记时间版)', + // feature: 'toc_DualMarriageStatusRegisterTime', + // desc: '双人婚姻状态按登记时间查询', + // icon: 'zrrsczt_icon.svg', + // iconFrom: 'category', + // }, + ], + }, +}; + +/** 根据 category 获取配置 */ +export function getInquireCategoryConfig(category) { + return inquireCategoryConfig[category] || null; +} + +/** 根据 category 获取页面标题(用于导航栏) */ +export function getInquireCategoryTitle(category) { + const config = inquireCategoryConfig[category]; + return config ? config.title : "选择查询"; +} diff --git a/src/router/index.js b/src/router/index.js index b721bb0..7591879 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,6 +1,7 @@ import { createRouter, createWebHistory } from 'vue-router' import NProgress from 'nprogress' import GlobalLayout from '@/layouts/GlobalLayout.vue' +import { getInquireCategoryTitle } from '@/config/inquireCategories' import HomeLayout from '@/layouts/HomeLayout.vue' import PageLayout from '@/layouts/PageLayout.vue' import index from '@/views/index.vue' @@ -16,13 +17,10 @@ const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), // 路由切换时的滚动行为 scrollBehavior(to, from, savedPosition) { - // 如果有保存的位置(浏览器前进/后退) if (savedPosition) { return savedPosition; - } else { - // 否则滚动到顶部 - return { top: 0, behavior: "smooth" }; } + return { top: 0 }; }, routes: [ { @@ -149,6 +147,12 @@ const router = createRouter({ component: () => import('@/views/AgentServiceAgreement.vue'), meta: { title: '信息技术服务合同' }, }, + { + path: '/inquire/category/:category', + name: 'inquireCategory', + component: () => import('@/views/InquireCategory.vue'), + meta: { title: '选择查询' }, + }, { path: '/inquire/:feature', name: 'inquire', @@ -361,6 +365,10 @@ NProgress.configure({ // 路由导航守卫 router.beforeEach(async (to, from, next) => { NProgress.start(); // 启动进度条 + // 二级查询分类页:根据 category 动态设置导航栏标题 + if (to.name === 'inquireCategory' && to.params.category) { + to.meta.title = getInquireCategoryTitle(to.params.category); + } const isAuthenticated = localStorage.getItem("token"); const agentStore = useAgentStore(); const userStore = useUserStore(); diff --git a/src/ui/CFLX3A9B.vue b/src/ui/CFLX3A9B.vue new file mode 100644 index 0000000..19b3e7a --- /dev/null +++ b/src/ui/CFLX3A9B.vue @@ -0,0 +1,309 @@ + + + + + diff --git a/src/ui/CIVYZ6M8P.vue b/src/ui/CIVYZ6M8P.vue new file mode 100644 index 0000000..f016f79 --- /dev/null +++ b/src/ui/CIVYZ6M8P.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/src/ui/CIVYZ9K7F.vue b/src/ui/CIVYZ9K7F.vue new file mode 100644 index 0000000..b7bc40f --- /dev/null +++ b/src/ui/CIVYZ9K7F.vue @@ -0,0 +1,227 @@ + + + + + diff --git a/src/ui/CIVYZA1B3.vue b/src/ui/CIVYZA1B3.vue new file mode 100644 index 0000000..1e363b3 --- /dev/null +++ b/src/ui/CIVYZA1B3.vue @@ -0,0 +1,239 @@ + + + + + diff --git a/src/ui/CJRZQ0B6Y.vue b/src/ui/CJRZQ0B6Y.vue new file mode 100644 index 0000000..3d02270 --- /dev/null +++ b/src/ui/CJRZQ0B6Y.vue @@ -0,0 +1,235 @@ + + + + + diff --git a/src/ui/CJRZQACAB.vue b/src/ui/CJRZQACAB.vue new file mode 100644 index 0000000..c30c11b --- /dev/null +++ b/src/ui/CJRZQACAB.vue @@ -0,0 +1,227 @@ + + + + + diff --git a/src/ui/CQCXG1H7Y.vue b/src/ui/CQCXG1H7Y.vue new file mode 100644 index 0000000..ed33405 --- /dev/null +++ b/src/ui/CQCXG1H7Y.vue @@ -0,0 +1,204 @@ + + + + + diff --git a/src/ui/CQCXG1U4U.vue b/src/ui/CQCXG1U4U.vue new file mode 100644 index 0000000..40d978f --- /dev/null +++ b/src/ui/CQCXG1U4U.vue @@ -0,0 +1,374 @@ + + + + + diff --git a/src/ui/CQCXG3Y6B.vue b/src/ui/CQCXG3Y6B.vue new file mode 100644 index 0000000..ebdf9f9 --- /dev/null +++ b/src/ui/CQCXG3Y6B.vue @@ -0,0 +1,284 @@ + + + + + diff --git a/src/ui/CQCXG3Z3L.vue b/src/ui/CQCXG3Z3L.vue new file mode 100644 index 0000000..785fba2 --- /dev/null +++ b/src/ui/CQCXG3Z3L.vue @@ -0,0 +1,288 @@ + + + + + diff --git a/src/ui/CQCXG4D2E.vue b/src/ui/CQCXG4D2E.vue new file mode 100644 index 0000000..c584432 --- /dev/null +++ b/src/ui/CQCXG4D2E.vue @@ -0,0 +1,126 @@ + + + + + diff --git a/src/ui/CQCXG4I1Z.vue b/src/ui/CQCXG4I1Z.vue new file mode 100644 index 0000000..dbff5dd --- /dev/null +++ b/src/ui/CQCXG4I1Z.vue @@ -0,0 +1,256 @@ + + + + + diff --git a/src/ui/CQCXG5U0Z.vue b/src/ui/CQCXG5U0Z.vue new file mode 100644 index 0000000..20a7806 --- /dev/null +++ b/src/ui/CQCXG5U0Z.vue @@ -0,0 +1,212 @@ + + + + + diff --git a/src/ui/CQCXG6B4E.vue b/src/ui/CQCXG6B4E.vue new file mode 100644 index 0000000..f9cc114 --- /dev/null +++ b/src/ui/CQCXG6B4E.vue @@ -0,0 +1,493 @@ + + + + + diff --git a/src/ui/CQCXGGB2Q.vue b/src/ui/CQCXGGB2Q.vue new file mode 100644 index 0000000..a06a5c8 --- /dev/null +++ b/src/ui/CQCXGGB2Q.vue @@ -0,0 +1,216 @@ + + + + + diff --git a/src/ui/CQCXGP00W.vue b/src/ui/CQCXGP00W.vue new file mode 100644 index 0000000..c9b5083 --- /dev/null +++ b/src/ui/CQCXGP00W.vue @@ -0,0 +1,634 @@ + + + + + diff --git a/src/ui/CQCXGY7F2.vue b/src/ui/CQCXGY7F2.vue new file mode 100644 index 0000000..d4cbf09 --- /dev/null +++ b/src/ui/CQCXGY7F2.vue @@ -0,0 +1,228 @@ + + + + + diff --git a/src/ui/CQCXGYTS2.vue b/src/ui/CQCXGYTS2.vue new file mode 100644 index 0000000..be1cee4 --- /dev/null +++ b/src/ui/CQCXGYTS2.vue @@ -0,0 +1,250 @@ + + + + + diff --git a/src/ui/CQVehicleGeneric.vue b/src/ui/CQVehicleGeneric.vue new file mode 100644 index 0000000..e92887e --- /dev/null +++ b/src/ui/CQVehicleGeneric.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/src/ui/CQYGL2S0W.vue b/src/ui/CQYGL2S0W.vue new file mode 100644 index 0000000..ed53e4f --- /dev/null +++ b/src/ui/CQYGL2S0W.vue @@ -0,0 +1,479 @@ + + + + + diff --git a/src/ui/CQYGL5F6A.vue b/src/ui/CQYGL5F6A.vue new file mode 100644 index 0000000..99629dd --- /dev/null +++ b/src/ui/CQYGL5F6A.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/src/ui/CQYGL66SL.vue b/src/ui/CQYGL66SL.vue new file mode 100644 index 0000000..f00c8c5 --- /dev/null +++ b/src/ui/CQYGL66SL.vue @@ -0,0 +1,542 @@ + + + + + diff --git a/src/ui/CYYSY3M8S.vue b/src/ui/CYYSY3M8S.vue new file mode 100644 index 0000000..256694f --- /dev/null +++ b/src/ui/CYYSY3M8S.vue @@ -0,0 +1,212 @@ + + + + + diff --git a/src/ui/CYYSY6F2B.vue b/src/ui/CYYSY6F2B.vue new file mode 100644 index 0000000..20ecc6f --- /dev/null +++ b/src/ui/CYYSY6F2B.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/src/ui/CYYSY9E4A.vue b/src/ui/CYYSY9E4A.vue new file mode 100644 index 0000000..ad237a7 --- /dev/null +++ b/src/ui/CYYSY9E4A.vue @@ -0,0 +1,124 @@ + + + + + diff --git a/src/ui/CYYSYE7V5.vue b/src/ui/CYYSYE7V5.vue new file mode 100644 index 0000000..4d84c8c --- /dev/null +++ b/src/ui/CYYSYE7V5.vue @@ -0,0 +1,192 @@ + + + + + diff --git a/src/ui/CYYSYF2T7.vue b/src/ui/CYYSYF2T7.vue new file mode 100644 index 0000000..3a20734 --- /dev/null +++ b/src/ui/CYYSYF2T7.vue @@ -0,0 +1,210 @@ + + + + + diff --git a/src/ui/CYYSYK8R3.vue b/src/ui/CYYSYK8R3.vue new file mode 100644 index 0000000..12e8f8d --- /dev/null +++ b/src/ui/CYYSYK8R3.vue @@ -0,0 +1,218 @@ + + + + + diff --git a/src/ui/CYYSYK9R4.vue b/src/ui/CYYSYK9R4.vue new file mode 100644 index 0000000..6109bd7 --- /dev/null +++ b/src/ui/CYYSYK9R4.vue @@ -0,0 +1,216 @@ + + + + + diff --git a/src/ui/CYYSYP0T4.vue b/src/ui/CYYSYP0T4.vue new file mode 100644 index 0000000..9040632 --- /dev/null +++ b/src/ui/CYYSYP0T4.vue @@ -0,0 +1,172 @@ + + + + + diff --git a/src/ui/CYYSYS9W1.vue b/src/ui/CYYSYS9W1.vue new file mode 100644 index 0000000..4f88423 --- /dev/null +++ b/src/ui/CYYSYS9W1.vue @@ -0,0 +1,151 @@ + + + + + diff --git a/src/ui/QCXG5F3A.vue b/src/ui/QCXG5F3A.vue new file mode 100644 index 0000000..20a62da --- /dev/null +++ b/src/ui/QCXG5F3A.vue @@ -0,0 +1,126 @@ + + + + + diff --git a/src/views/HistoryQuery.vue b/src/views/HistoryQuery.vue index 87ff478..f45a817 100644 --- a/src/views/HistoryQuery.vue +++ b/src/views/HistoryQuery.vue @@ -48,8 +48,9 @@ const onLoad = () => { } } +// 允许进入报告页:成功直接看报告,查询中可看加载并轮询,失败/退款不跳转 function toDetail(item) { - if (item.query_state != "success") return + if (item.query_state === "failed" || item.query_state === "refunded") return router.push({ path: '/report', query: { orderId: item.order_id } }); } diff --git a/src/views/InquireCategory.vue b/src/views/InquireCategory.vue new file mode 100644 index 0000000..ffbba3d --- /dev/null +++ b/src/views/InquireCategory.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/src/views/Report.vue b/src/views/Report.vue index 1c5bb2a..d6e65bb 100644 --- a/src/views/Report.vue +++ b/src/views/Report.vue @@ -1,13 +1,22 @@ @@ -15,6 +24,8 @@ import LEmpty from "@/components/LEmpty.vue"; const route = useRoute(); +const router = useRouter(); + const feature = ref(""); const reportData = ref([]); const reportParams = ref({}); @@ -27,13 +38,11 @@ const orderNo = ref(""); const queryState = ref(""); const pollingInterval = ref(null); - onBeforeMount(() => { const query = new URLSearchParams(window.location.search); orderNo.value = query.get("out_trade_no"); orderId.value = query.get("order_id"); - if (!orderNo.value && !orderId.value) { orderId.value = route.query.orderId; orderNo.value = route.query.orderNo; @@ -50,8 +59,6 @@ onBeforeUnmount(() => { } }); - - const getReport = async () => { let queryUrl = ""; if (orderNo.value) { @@ -72,7 +79,6 @@ const getReport = async () => { reportData.value = data.value.data.query_data.sort((a, b) => { return a.feature.sort - b.feature.sort; }); - // console.log("reportData", reportData.value[1].data.data) reportParams.value = data.value.data.query_params; reportName.value = data.value.data.product_name; @@ -85,11 +91,11 @@ const getReport = async () => { pollingInterval.value = null; } } else if (queryState.value === "pending") { - // 如果是pending状态且没有轮询,启动轮询 + // 如果是 pending 状态且没有轮询,启动轮询 if (!pollingInterval.value) { pollingInterval.value = setInterval(() => { getReport(); - }, 2000); // 每2秒轮询一次 + }, 2000); // 每 2 秒轮询一次 } } else if (queryState.value === "failed") { isEmpty.value = true; @@ -103,15 +109,21 @@ const getReport = async () => { } else if (data.value.code === 200003) { isEmpty.value = true; isDone.value = true; - } else if (data.value.code === 200002) { - isPending.value = true; - isDone.value = true; } } }; + +const toHistory = () => { + router.push("/historyQuery"); +};