Node.js 中间件实战:对接天远借贷行为接口并清洗为 ECharts 数据

1. 让风控数据"可视化"

在信贷审核系统的后台或 H5 报告页中,风控专员往往需要一眼看穿用户的借贷趋势。是平稳借贷,还是最近两个月突然爆发?

天远数据借贷行为验证API (JRZQ8203)提供了极其宝贵的 T0(当前)至 T11(过去11个月) 的时间序列数据 。这些数据包含借贷次数、机构数和还款压力等级。

然而,API 返回的是扁平化的 Key-Value 结构(如 tl_id_t0_nbank_num, tl_id_t1_nbank_num...)。直接把这些数据丢给前端不仅增加了前端的处理负担,还暴露了加密细节。

Node.js 作为天然的 BFF (Backend for Frontend) 首选语言,凭借其对 JSON 的原生支持和高效的 IO 能力,非常适合充当这个"转换器":对接天远 API,清洗数据,最终输出给前端标准的图表数据。

2. API 调用示例:Node.js Crypto 实战

Node.js 的原生 crypto 模块完美支持天远 API 要求的 AES-128-CBC 算法,且默认支持 PKCS7 填充,因此代码实现比 Go 或 Python 更为简洁。

2.1 接口配置

  • 接口地址https://api.tianyuanapi.com/api/v1/JRZQ8203
  • 加密规范:AES-128-CBC,IV 随机生成,Base64 输出 。

2.2 完整 Service 代码 (封装为 Class)

JavaScript

jsx 复制代码
const crypto = require('crypto');
const axios = require('axios');

class RiskService {
    constructor(accessId, accessKey) {
        this.accessId = accessId;
        // 确保密钥是 Buffer 类型
        this.accessKey = Buffer.from(accessKey, 'utf8');
        this.apiUrl = 'https://api.tianyuanapi.com/api/v1/JRZQ8203';
    }

    /**
     * AES-128-CBC 加密
     * Node.js createCipheriv 默认使用 PKCS7 填充,无需手动处理
     */
    encrypt(data) {
        const iv = crypto.randomBytes(16); // 随机生成 16 字节 IV
        const cipher = crypto.createCipheriv('aes-128-cbc', this.accessKey, iv);
        
        const jsonStr = JSON.stringify(data);
        let encrypted = cipher.update(jsonStr, 'utf8');
        encrypted = Buffer.concat([encrypted, cipher.final()]);
        
        // 拼接 IV + 密文 -> Base64
        return Buffer.concat([iv, encrypted]).toString('base64');
    }

    /**
     * AES-128-CBC 解密
     */
    decrypt(base64Str) {
        const buffer = Buffer.from(base64Str, 'base64');
        const iv = buffer.slice(0, 16); // 提取前 16 字节 IV
        const content = buffer.slice(16); // 提取密文

        const decipher = crypto.createDecipheriv('aes-128-cbc', this.accessKey, iv);
        let decrypted = decipher.update(content);
        decrypted = Buffer.concat([decrypted, decipher.final()]);
        
        return JSON.parse(decrypted.toString('utf8'));
    }

    /**
     * 执行查询
     */
    async query(name, idCard, mobile) {
        const payload = {
            name: name,
            id_card: idCard,
            mobile_no: mobile
        };

        const encryptedData = this.encrypt(payload);

        try {
            // 添加时间戳防止缓存
            const res = await axios.post(`${this.apiUrl}?t=${Date.now()}`, {
                data: encryptedData
            }, {
                headers: {
                    'Access-Id': this.accessId,
                    'Content-Type': 'application/json'
                }
            });

            if (res.data.code === 0) {
                // 解密响应数据
                return this.decrypt(res.data.data);
            } else {
                throw new Error(`API Error: ${res.data.message}`);
            }
        } catch (error) {
            console.error('Risk Check Failed:', error.message);
            return null;
        }
    }
}

// --- 使用示例 ---
(async () => {
    const service = new RiskService("您的AccessId", "您的16位AccessKey");
    const result = await service.query("测试用户", "110101199001011234", "13800138000");
    
    if (result && result.flag_totalloan === '1') {
        console.log("当前还款压力等级:", result.tl_id_t0_nbank_reamt);
    }
})();

3. 核心数据结构解析:JS 动态映射

天远 API 返回的字段虽然多(例如 tl_id_t0_...tl_id_t11_...),但非常有规律 。利用 JavaScript 的动态对象属性访问特性,我们可以轻松通过循环来处理这些数据,而不需要像 Java 那样定义庞大的 DTO。

3.1 数据清洗:扁平转数组

为了方便前端 ECharts 绘图,我们需要把 T0-T11 的数据转换成数组。

JavaScript

jsx 复制代码
/**
 * 将扁平的 API 响应转换为前端图表所需的数组
 * @param {Object} rawData 解密后的 API 原始数据
 */
function formatForChart(rawData) {
    const timeSeries = [];
    const pressureSeries = [];
    const orgCountSeries = [];

    // 遍历 T0 到 T11 (API 提供近12个月的切片数据)
    for (let i = 0; i < 12; i++) {
        // 动态构建 Key
        const pressureKey = `tl_id_t${i}_nbank_reamt`; // 还款压力
        const orgKey = `tl_id_t${i}_nbank_org`;        // 机构数

        // 提取数据,注意 API 返回的是字符串,需转数字
        // 倒序插入:因为 T0 是当前,图表通常希望 T11(过去) -> T0(现在)
        timeSeries.unshift(`T${i}`); 
        pressureSeries.unshift(parseInt(rawData[pressureKey] || 0));
        orgCountSeries.unshift(parseInt(rawData[orgKey] || 0));
    }

    return {
        categories: timeSeries, // x轴
        series: [
            { name: '还款压力', data: pressureSeries },
            { name: '借贷机构数', data: orgCountSeries }
        ],
        // 提取一些关键汇总指标
        summary: {
            flag: rawData.flag_totalloan,
            lastLoanTime: rawData.tl_id_eletail_lasttime,
            loanType: rawData.tl_id_eletail_lasttype // a-h 类型
        }
    };
}

3.2 关键字段解读

  • flag_totalloan : 借贷行为输出标识。
    • 1: 成功。
    • 0: 未匹配上(可能为白户)。
    • 98: 输入信息不足。
    • BFF 层逻辑 :如果为 0,前端应显示"无借贷记录"状态页 。
  • tl_id_t0_nbank_reamt (1-101) : 预测当前时间近一年在非银机构的应还款等级
    • 业务含义:数值越高,代表用户本月需要偿还的金额压力越大。如果曲线在 T2-T0 期间陡峭上升,说明近期负债急剧增加 。

4. 应用价值分析:BFF 层的灵活性

场景一:借贷压力可视化

前端直接调用 Node.js 接口,获取 formatForChart 处理后的数据。

  • 可视化效果:使用双轴折线图。左轴显示"机构数"(0-20),右轴显示"压力指数"(0-100)。
  • 价值:信贷审核员无需阅读枯燥的表格,一眼就能看出曲线是否"抬头"。

场景二:基于规则的 API 聚合

在 BFF 层,我们可以将借贷行为验证 (JRZQ8203) 与其他业务逻辑聚合。

  • 逻辑流
    1. 调用天远 API。
    2. 检查 tl_id_eletail_lasttype。如果是 c (持牌网络小贷),标记为普通风险;如果是 h (其他),标记为高危 。
    3. 检查 tl_id_m3_nbank_passnum。如果 > 10,标记为多头借贷 。
    4. 最终输出 :向前端仅返回 { riskLevel: "HIGH", reason: "近期多头借贷且渠道下沉" },屏蔽原始数据的复杂性。

场景三:Serverless 降本增效

将上述 Node.js 代码部署为 AWS Lambda 或 阿里云 FC 函数。

  • 优势:风控查询通常是偶发的(有用户申请时才触发)。Serverless 架构按调用次数计费,且自动扩缩容,完美匹配天远 API 按量计费的模式,将运维成本降至最低。

5. 总结

在 Node.js 环境下对接 天远借贷行为验证API 具有得天独厚的优势:

  1. 开发快:原生 Crypto 库直接搞定 AES 加密,无需折腾 Padding。
  2. 处理快:JavaScript 处理 API 返回的大型 JSON 对象(130+ 字段)非常灵活,无需定义繁琐的 Struct 或 Class。
  3. 体验好:通过 BFF 层的数据清洗,可以直接为前端提供可视化的图表数据,极大提升风控系统的用户体验。

通过这套方案,您不仅是在调用一个数据接口,更是在搭建一个智能化的风控数据中台。

相关推荐
极客先躯2 小时前
java的线上诊断工具大全
java·大数据·开发语言·内存管理·生产·诊断工具
天呐草莓2 小时前
企业微信自动打标签教程
大数据·python·微信·微信小程序·小程序·企业微信
laozhao4322 小时前
各方面横向对比,标标达和剑鱼标讯谁更正规?
大数据·人工智能
汽车仪器仪表相关领域2 小时前
ZRT-I 精密减速器测试系统
大数据·运维·功能测试·安全·单元测试·负载均衡·压力测试
数字护盾(和中)2 小时前
AI正在重塑网络安全:自动化渗透测试如何让企业“先攻后防”?
大数据·运维
Elastic 中国社区官方博客2 小时前
Elasticsearch:圣诞晚餐 BBQ
大数据·人工智能·elk·elasticsearch·搜索引擎·ai·全文检索
无泪无花月隐星沉2 小时前
uos server 1070e部署Hadoop
大数据·运维·服务器·hadoop·分布式·uos·国产化os
说私域2 小时前
基于AI智能名片链动2+1模式S2B2C商城小程序的商户端微商平台构建研究
大数据·人工智能·小程序
kuankeTech2 小时前
生鲜进出口贸易数字化转型:智慧外贸ERP解决方案破解行业痛点
大数据·人工智能·开源软件·软件开发·erp