92451 67c85678e6 feat: 接入网商银行每日动账明细 (#831)
Co-authored-by: 92451 <924518135@qq.com>
Co-committed-by: 92451 <924518135@qq.com>
2026-11-02 20:58:42 +08:00

74 lines
2.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
export const BASE = path.dirname(fileURLToPath(import.meta.url));
export const ROOT = path.resolve(BASE, '../..');
export const CONFIG_FILE = path.resolve(
process.env.WANGSHANG_BANK_CONFIG_FILE
|| path.join(ROOT, 'runtime/private/wangshang-bank-accounts.json'),
);
export const PROFILE_ROOT = path.resolve(
process.env.WANGSHANG_BANK_PROFILE_ROOT
|| path.join(ROOT, 'runtime/private/wangshang-bank-profiles'),
);
export function accountDigits(value) {
return String(value ?? '').replace(/\D/g, '');
}
export function maskAccount(value) {
const digits = accountDigits(value);
return digits.length >= 4 ? `****${digits.slice(-4)}` : '****';
}
export function profileDirectory(account) {
const key = crypto
.createHash('sha256')
.update(accountDigits(account.bank_account))
.digest('hex')
.slice(0, 16);
return path.join(PROFILE_ROOT, key);
}
export function loadAccounts() {
if (!fs.existsSync(CONFIG_FILE)) {
throw new Error('缺少 runtime/private/wangshang-bank-accounts.json,请先运行 import-accounts.ps1');
}
const payload = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
const source = Array.isArray(payload) ? payload : payload.accounts;
if (!Array.isArray(source) || source.length === 0) {
throw new Error('网商银行私有配置没有账户');
}
const accounts = source.map((item, index) => {
const company = String(item.company ?? '').trim();
const alipayAccount = String(item.alipay_account ?? '').trim();
const alipayPassword = String(item.alipay_password ?? item.password ?? '');
const bankAccount = accountDigits(item.bank_account);
const accountShort = String(item.account_short ?? '').trim();
if (!company || !alipayAccount || !alipayPassword || bankAccount.length < 6 || !accountShort) {
throw new Error(`网商银行私有配置第 ${index + 1} 行缺少公司、支付宝账号、密码、网商账号或账户简称`);
}
return {
company,
alipay_account: alipayAccount,
alipay_password: alipayPassword,
bank_account: bankAccount,
account_short: accountShort,
};
});
if (new Set(accounts.map((item) => item.bank_account)).size !== accounts.length) {
throw new Error('网商银行私有配置存在重复账号');
}
return accounts;
}
export function accountLabel(account) {
return `${account.company}(${maskAccount(account.bank_account)})`;
}