chore: remove obsolete icon catalog bootstrap scripts
This commit is contained in:
1 parent
312a5ccb86
commit
0b2588e09c
5 files changed
+3
-138
No files matched your search
@@ -54,6 +54,8 @@ pnpm check:staged # git add 后,提交前检查本地凭证和禁止提交的
|
||||
|
||||
预置银行、支付平台与交易所等共 36 个图标,资源及来源清单在 `apps/api/assets/icons`;银行来自公开银行标识库,支付平台来自官方网站资源及 Simple Icons。图标版权与商标归相应品牌所有,用于识别账户,不代表品牌合作或授权。运行 `pnpm --filter @worthpath/api icons:seed` 初始化共享库或更新固定 ID 的内置透明图标,不修改用户上传图标或财务数据。可离线使用已提交的 PNG,无需访问外部图标网站。
|
||||
|
||||
图库的首次下载、固定品牌扩充和 ICO 转换脚本已移除。后续维护直接更新 PNG 与 `sources.json` 来源清单,再通过 `icons:seed` 更新内置图库。开发、迁移、诊断、隔离测试、性能基准和回归测试入口继续保留;一次性工具使用完后及时清理。
|
||||
|
||||
当前 ZIP v9 的 transfers.json 保存转账双方、金额、手续费及配对历史,恢复时重建关系;icons.json 保存图标名称、图片和内容校验值。恢复图标为私有,相同图片复用,避免自动公开;不支持旧 ZIP 或单文件 JSON。清空个人数据会删除私有图标,已发布共享图标保留供其他用户使用。
|
||||
|
||||
## 账户转账与显示设置
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
"""Optional catalog maintenance: convert downloaded ICO files using Pillow.
|
||||
|
||||
Normal installs use the committed PNG assets and do not need Python.
|
||||
Run after download-icons.cjs, before icons:seed.
|
||||
"""
|
||||
from pathlib import Path
|
||||
from PIL import Image
|
||||
|
||||
folder = Path(__file__).resolve().parent.parent / 'assets' / 'icons'
|
||||
for source in folder.glob('*.ico'):
|
||||
with Image.open(source) as image:
|
||||
image.convert('RGBA').save(source.with_suffix('.png'))
|
||||
source.unlink()
|
||||
print('Catalog ICO sources converted to PNG.')
|
||||
@@ -1,73 +0,0 @@
|
||||
// Explicit, fixed public sources only. No user account information is sent.
|
||||
const fs = require('node:fs/promises');
|
||||
const path = require('node:path');
|
||||
const sharp = require('sharp');
|
||||
const { createHash } = require('node:crypto');
|
||||
const dir = path.join(__dirname, '../assets/icons');
|
||||
async function main() {
|
||||
await fs.mkdir(dir, { recursive: true });
|
||||
const response = await fetch('https://api.github.com/repos/cellier/bank-icon-cn/contents/png/72');
|
||||
if (!response.ok) throw Error();
|
||||
const banks = await response.json();
|
||||
const names = [
|
||||
'中国工商银行',
|
||||
'中国农业银行',
|
||||
'中国建设银行',
|
||||
'中国银行',
|
||||
'交通银行',
|
||||
'招商银行',
|
||||
'中信银行',
|
||||
'中国光大银行',
|
||||
'中国民生银行',
|
||||
'兴业银行',
|
||||
'平安银行',
|
||||
'上海浦东发展银行',
|
||||
'广发银行',
|
||||
'华夏银行',
|
||||
'北京银行',
|
||||
'上海银行',
|
||||
'浙商银行',
|
||||
];
|
||||
const sources = names.map((name) => ({
|
||||
name,
|
||||
source: banks.find((b) => b.name === name + '@3x.png')?.download_url,
|
||||
}));
|
||||
sources.push(
|
||||
{ name: '支付宝', source: 'https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/alipay.svg' },
|
||||
{ name: '微信', source: 'https://res.wx.qq.com/a/wx_fed/assets/res/NTI4MWU5.ico' },
|
||||
{ name: '京东金融', source: 'https://is1-ssl.mzstatic.com/image/thumb/Purple211/v4/7d/74/af/7d74af96-af89-ae14-cbf5-5bbd89859ab7/AppIcon-0-1x_U007epad-0-1-0-85-220-0.png/512x512bb.jpg', preserveWhite: true },
|
||||
);
|
||||
const manifest = [];
|
||||
for (const item of sources) {
|
||||
if (!item.source) throw Error('Missing catalog source');
|
||||
const res = await fetch(item.source, { signal: AbortSignal.timeout(20000) });
|
||||
if (!res.ok) throw Error('Public icon download failed');
|
||||
const raw = Buffer.from(await res.arrayBuffer());
|
||||
// Alipay's catalog SVG is an inverse mark. Mask within the glyph bounds to omit its frame.
|
||||
const glyphPath = item.name === '支付宝' ? raw.toString().match(/<path d="([^"]+)"/)[1] : '';
|
||||
const rasterSource = item.name === '支付宝' ? Buffer.from(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><mask id="glyph"><rect x="1.5" y="3.17" width="22.3" height="17" fill="white"/><path d="${glyphPath}" fill="black"/></mask></defs><rect width="24" height="24" fill="#1677ff" mask="url(#glyph)"/></svg>`) : raw;
|
||||
const file =
|
||||
String(manifest.length + 1).padStart(2, '0') +
|
||||
(item.source.endsWith('.ico') ? '.ico' : '.png');
|
||||
if (file.endsWith('.ico')) await fs.writeFile(path.join(dir, file), raw);
|
||||
else
|
||||
await fs.writeFile(
|
||||
path.join(dir, file),
|
||||
await sharp(rasterSource, { density: 768 })
|
||||
.resize(256, 256, { fit: 'inside', withoutEnlargement: true })
|
||||
.png()
|
||||
.toBuffer(),
|
||||
);
|
||||
manifest.push({
|
||||
...item,
|
||||
file: file.replace('.ico', '.png'),
|
||||
sha256: createHash('sha256').update(raw).digest('hex'),
|
||||
});
|
||||
}
|
||||
await fs.writeFile(path.join(dir, 'sources.json'), JSON.stringify(manifest, null, 2) + '\n');
|
||||
console.log(`Downloaded ${manifest.length} public icons; convert ICO sources before seeding.`);
|
||||
}
|
||||
main().catch(() => {
|
||||
console.error('Icon source download failed; existing database icons were not changed.');
|
||||
process.exitCode = 1;
|
||||
});
|
||||
@@ -1,50 +0,0 @@
|
||||
"""Fetch public brand icons from the listed official websites; keep existing catalog."""
|
||||
import hashlib, io, json, re, sys, urllib.request, urllib.parse
|
||||
from pathlib import Path
|
||||
from PIL import Image
|
||||
folder = Path(__file__).resolve().parent.parent / 'assets' / 'icons'
|
||||
catalog = json.loads((folder / 'sources.json').read_text(encoding='utf-8'))
|
||||
brands = [('汇丰香港', 'https://www.hsbc.com.hk'), ('恒生银行', 'https://www.hangseng.com'), ('中银香港', 'https://www.bochk.com/en'), ('渣打香港', 'https://www.sc.com/hk'), ('东亚银行', 'https://www.hkbea.com'), ('星展香港', 'https://www.dbs.com.hk'), ('花旗香港', 'https://www.citibank.com.hk'), ('币安 Binance', 'https://www.binance.com'), ('Gate', 'https://www.gate.com'), ('Bybit', 'https://www.bybit.com'), ('Bitget', 'https://www.bitget.com')]
|
||||
brands += [('抖音月付', 'https://www.douyinpay.com'), ('东方财富', 'https://about.eastmoney.com/about/product')]
|
||||
brands += [('ZA BANK 众安银行', 'https://bank.za.group'), ('大象银行 EleBank', 'https://www.elebank.com'), ('微众银行 WeBank', 'https://www.webank.com')]
|
||||
if len(sys.argv) > 1:
|
||||
brands = [item for item in brands if item[0] in sys.argv[1:]]
|
||||
|
||||
def get(url):
|
||||
return urllib.request.urlopen(urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'}), timeout=20).read()
|
||||
failed = []
|
||||
for name, site in brands:
|
||||
if any(v['name'] == name for v in catalog): continue
|
||||
urls = {'抖音月付': ['https://p26-infras.byteimg.com/static-assets/be18bb89d2ceeec6407aae38dc5e894c.png~tplv-49obo7mizy-png75.png'], '东方财富': ['https://g1.dfcfw.com/g4/202307/20230731180250.png'], '币安 Binance': ['https://bin.bnbstatic.com/static/images/common/favicon.ico', 'https://bin.bnbstatic.com/static/images/common/favicon.png'], '中银香港': ['https://www.bochk.com/dam/bochk/desktop/top/favicon.ico', 'https://www.bochk.com/favicon.ico'], '大象银行 EleBank': ['https://is1-ssl.mzstatic.com/image/thumb/Purple211/v4/d4/bc/60/d4bc6004-3898-c9c3-3571-f3ffe4b46b48/Bank-Airstar-0-0-1x_U007epad-0-1-sRGB-85-220.png/512x512bb.jpg']}.get(name, [])
|
||||
if name == '微众银行 WeBank':
|
||||
try:
|
||||
script = get('https://tctp.tctpwebankcdn.net/owb-res/owb-res/assets/mainGenerator.811f2078.js').decode('utf-8')
|
||||
logo = re.search(r'Tr="(data:image/png;base64,[^"]+)"', script)
|
||||
if logo: urls.insert(0, logo.group(1))
|
||||
except Exception: pass
|
||||
try:
|
||||
html = get(site).decode('utf-8', errors='replace')
|
||||
for tag in re.findall(r'<link\b[^>]*>', html, re.I):
|
||||
attrs = dict(re.findall(r'([\w-]+)=["\']([^"\']*)["\']', tag))
|
||||
if 'icon' in attrs.get('rel', '').lower() and attrs.get('href'): urls.append(urllib.parse.urljoin(site + '/', attrs['href']))
|
||||
except Exception: pass
|
||||
urls += [urllib.parse.urljoin(site + '/', '/favicon.ico'), urllib.parse.urljoin(site + '/', '/favicon.png')]
|
||||
for url in dict.fromkeys(urls):
|
||||
try:
|
||||
raw = get(url)
|
||||
im = Image.open(io.BytesIO(raw)).convert('RGBA')
|
||||
if name == '东方财富':
|
||||
# Official horizontal logo: retain its standalone symbol for square account cards.
|
||||
im = im.crop((int(im.width * 40 / 256), 0, int(im.width * 80 / 256), im.height))
|
||||
if im.getbbox(): im = im.crop(im.getbbox())
|
||||
im.thumbnail((256,256))
|
||||
out = io.BytesIO(); im.save(out, 'PNG'); png = out.getvalue()
|
||||
file = str(len(catalog) + 1).zfill(2) + '.png'
|
||||
(folder / file).write_bytes(png)
|
||||
catalog.append({'name':name,'source':site if url.startswith('data:') else url,'file':file,'sha256':hashlib.sha256(raw).hexdigest()})
|
||||
print('Added:', name)
|
||||
break
|
||||
except Exception: continue
|
||||
else: failed.append(name)
|
||||
(folder / 'sources.json').write_text(json.dumps(catalog, ensure_ascii=False, indent=2) + '\n', encoding='utf-8')
|
||||
if failed: print('Unavailable:', ', '.join(failed)); raise SystemExit(1)
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
内置图库新增独立命名的“抖音月付”和“东方财富”,现共 36 项。可在账户新增/编辑的图标选择器或设置页图库按名称搜索并选择,复用现有图标关联和完整备份逻辑。
|
||||
|
||||
“抖音月付”采用[抖音支付官网](https://www.douyinpay.com/)公开的抖音品牌标识,并非另行绘制的月付专属标识。“东方财富”采用[东方财富官方产品页](https://about.eastmoney.com/about/product)的品牌符号,从横向标识中保留适合账户卡片的独立图形。公开资源地址和原始内容 SHA-256 记录在 apps/api/assets/icons/sources.json,expand-icons.py 同步添加可复现来源。
|
||||
“抖音月付”采用[抖音支付官网](https://www.douyinpay.com/)公开的抖音品牌标识,并非另行绘制的月付专属标识。“东方财富”采用[东方财富官方产品页](https://about.eastmoney.com/about/product)的品牌符号,从横向标识中保留适合账户卡片的独立图形。公开资源地址和原始内容 SHA-256 记录在 apps/api/assets/icons/sources.json。图标与来源清单已保存;2026-10-05 清理已完成的一次性下载、扩充和 ICO 转换脚本,保留 icons:seed 初始化入口。
|
||||
|
||||
图像均保存为静态 PNG,初始化时复用现有尺寸限制、透明处理和固定内置 ID。无需数据库结构变更;已运行 icons:seed,保留用户上传图标与财务记录。
|
||||
|
||||
|
||||
Reference in new issue
Block a user