feat: vCard 扩展 + 格式扩展 + 解码透视矫正 — v0.3.0
Phase 1: 格式扩展 - png.rs → image.rs,OutputFormat 枚举 (PNG/BMP/JPEG/WebP) - CLI -f/--format,Web fmt 参数扩展,image crate +bmp feature Phase 2: 解码增强 - 新增 decoder/perspective.rs — 旋转矫正(MVP) - auto_correct: finder 检测→计算旋转角→仿射变换→再解码 - decode_image 自动重试矫正流水线 Phase 3: vCard 扩展 - 新增 5 字段:TITLE/URL/BDAY/NOTE/PHOTO - Rust text_builder + TS qrText + VCardMode UI 同步 - CLI 新增 --title --vcard-url --birthday --note --photo - 中/英 i18n 翻译 测试: 81 Rust + 19 前端全部通过
This commit is contained in:
@@ -47,7 +47,12 @@
|
||||
"phone": "Phone",
|
||||
"email": "Email",
|
||||
"company": "Company",
|
||||
"address": "Address"
|
||||
"title": "Title",
|
||||
"address": "Address",
|
||||
"url": "URL",
|
||||
"birthday": "Birthday",
|
||||
"note": "Note",
|
||||
"photo": "Photo URL"
|
||||
},
|
||||
"email": {
|
||||
"to": "To",
|
||||
|
||||
@@ -47,7 +47,12 @@
|
||||
"phone": "电话",
|
||||
"email": "邮箱",
|
||||
"company": "公司",
|
||||
"address": "地址"
|
||||
"title": "职位",
|
||||
"address": "地址",
|
||||
"url": "网址",
|
||||
"birthday": "生日",
|
||||
"note": "备注",
|
||||
"photo": "照片URL"
|
||||
},
|
||||
"email": {
|
||||
"to": "收件人",
|
||||
|
||||
@@ -8,7 +8,12 @@ const FIELDS = [
|
||||
{ key: 'phone', i18n: 'vcard.phone' },
|
||||
{ key: 'email', i18n: 'vcard.email' },
|
||||
{ key: 'company', i18n: 'vcard.company' },
|
||||
{ key: 'title', i18n: 'vcard.title' },
|
||||
{ key: 'address', i18n: 'vcard.address' },
|
||||
{ key: 'vcardUrl', i18n: 'vcard.url' },
|
||||
{ key: 'birthday', i18n: 'vcard.birthday' },
|
||||
{ key: 'note', i18n: 'vcard.note' },
|
||||
{ key: 'photo', i18n: 'vcard.photo' },
|
||||
];
|
||||
|
||||
export default function VCardMode() {
|
||||
|
||||
@@ -14,14 +14,26 @@ export function buildWifiText(formData: Record<string, string>): string {
|
||||
return `WIFI:T:${encryption};S:${ssid};P:${password};${hidden};`;
|
||||
}
|
||||
|
||||
/** 构造 vCard 字符串 */
|
||||
/** 构造 vCard 3.0 字符串(含扩展字段) */
|
||||
export function buildVCardText(formData: Record<string, string>): string {
|
||||
const name = formData.name || '';
|
||||
const phone = formData.phone || '';
|
||||
const email = formData.email || '';
|
||||
const company = formData.company || '';
|
||||
const address = formData.address || '';
|
||||
return `BEGIN:VCARD\nVERSION:3.0\nFN:${name}\nTEL:${phone}\nEMAIL:${email}\nORG:${company}\nADR:${address}\nEND:VCARD`;
|
||||
const title = formData.title || '';
|
||||
const url = formData.vcardUrl || '';
|
||||
const birthday = formData.birthday || '';
|
||||
const note = formData.note || '';
|
||||
const photo = formData.photo || '';
|
||||
let s = `BEGIN:VCARD\nVERSION:3.0\nFN:${name}\nTEL:${phone}\nEMAIL:${email}\nORG:${company}`;
|
||||
if (title) s += `\nTITLE:${title}`;
|
||||
if (address) s += `\nADR:${address}`;
|
||||
if (url) s += `\nURL:${url}`;
|
||||
if (birthday) s += `\nBDAY:${birthday}`;
|
||||
if (note) s += `\nNOTE:${note}`;
|
||||
if (photo) s += `\nPHOTO:${photo}`;
|
||||
return s + '\nEND:VCARD';
|
||||
}
|
||||
|
||||
/** 构造 mailto 链接 */
|
||||
|
||||
Reference in New Issue
Block a user