文件
OmniCard/mpuniapp/pages/owner/card/useCardQrcode.uts
wikiboss eec259a3a7 feat: 完成全系统30个功能点开发与E2E全链路验收 (8轮调度32个子代理闭环)
- 模块一: 出海案例作品集、博客动态发布、人名发音语音条、RTL阿语多语言切换
- 模块二: AI顾问人设配置、行业术语库润色、RAG切片沙盒调试、流式会话与意向留资卡片
- 模块三: 全球访客雷达大屏、多维加权意向算分、外部CRM对接推送、团队公海池流转
- 模块四: 移动端NFC安全挂失、NFC动态路由规则配置、动态防伪验签、展会制卡Zip批量导出
- 模块五: 组织架构与名片分配、移动端个人中心设置、离职交接与历史线索迁移、安全审计日志
- 模块六: Stripe国际信用卡订阅Webhook、独立二级域名与SSL检测、坐席配额预警、多币种发票
- 模块七: 纸质名片OCR解析入库、国际商务日程RFC 5545 ICS日历、微官网离线SWR预加载、展会实时排行榜大屏
- 模块八: 全球出海SEO OpenGraph元标签注入与社交爬虫探测、30点端到端全链路业务流集成测试套件
2026-09-20 23:47:47 +08:00

267 行
6.0 KiB
Plaintext

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

/**
* OmniCard AI (CRMmp) - 名片主参展分享码海报业务驱动层
* 解析 slug / id,拉取公开短链二维码,复制链接
*/
import { fetchCardQrcodeSvg } from '../../../common/api.uts';
import {
getCurrentLocale,
getOmniText,
OmniLocale,
} from '../../../common/locale.uts';
export type QrcodeQuery = {
slug?: string;
id?: string;
};
export type CardQrcodePoster = {
svg: string;
url: string;
};
export type LoadPosterApi = {
fetchCardQrcodeSvg: (slugOrId: string) => Promise<CardQrcodePoster>;
};
export type LoadPosterResult = {
svg: string;
url: string;
empty: boolean;
errorMessage: string;
};
export type QrcodeState = {
slugOrId: string;
svg: string;
url: string;
loading: boolean;
empty: boolean;
errorMessage: string;
};
export type QrcodeCopyKey =
| 'copyCta'
| 'generated'
| 'urlLabel'
| 'empty'
| 'error'
| 'loading'
| 'title';
const QRCODE_COPY: Record<OmniLocale, Record<QrcodeCopyKey, string>> = {
'zh-CN': {
title: '分享名片',
copyCta: '复制链接',
generated: '二维码已生成',
urlLabel: '短链',
empty: '暂无数据',
error: '出错了',
loading: '加载中...',
},
'en-US': {
title: 'Share Card',
copyCta: 'Copy link',
generated: 'QR code ready',
urlLabel: 'Short link',
empty: 'Nothing here yet',
error: 'Something went wrong',
loading: 'Loading...',
},
'ar-SA': {
title: 'مشاركة البطاقة',
copyCta: 'نسخ الرابط',
generated: 'رمز الاستجابة جاهز',
urlLabel: 'الرابط المختصر',
empty: 'لا توجد بيانات بعد',
error: 'حدث خطأ',
loading: 'جار التحميل...',
},
'es-ES': {
title: 'Compartir tarjeta',
copyCta: 'Copiar enlace',
generated: 'Codigo QR listo',
urlLabel: 'Enlace corto',
empty: 'Aun no hay datos',
error: 'Algo salio mal',
loading: 'Cargando...',
},
'de-DE': {
title: 'Karte teilen',
copyCta: 'Link kopieren',
generated: 'QR-Code bereit',
urlLabel: 'Kurzlink',
empty: 'Noch keine Daten',
error: 'Etwas ist schiefgelaufen',
loading: 'Wird geladen...',
},
'fr-FR': {
title: 'Partager la carte',
copyCta: 'Copier le lien',
generated: 'QR code pret',
urlLabel: 'Lien court',
empty: 'Aucune donnee',
error: 'Une erreur est survenue',
loading: 'Chargement...',
},
'ja-JP': {
title: '名刺をシェア',
copyCta: 'リンクをコピー',
generated: 'QRコードを生成しました',
urlLabel: 'ショートリンク',
empty: 'データがありません',
error: 'エラーが発生しました',
loading: '読み込み中...',
},
};
function trimText(value: string | number | null | undefined): string {
if (value == null) {
return '';
}
return String(value).trim();
}
/**
* 页面文案:能复用 locale.uts 的走词典,其余走本地七语表
*/
export function resolveQrcodeText(key: QrcodeCopyKey): string {
if (key === 'title') {
return getOmniText(getCurrentLocale(), 'card.share');
}
if (key === 'empty') {
return getOmniText(getCurrentLocale(), 'common.empty');
}
if (key === 'error') {
return getOmniText(getCurrentLocale(), 'common.error');
}
if (key === 'loading') {
return getOmniText(getCurrentLocale(), 'common.loading');
}
const locale = getCurrentLocale();
const bag = QRCODE_COPY[locale] != null ? QRCODE_COPY[locale] : QRCODE_COPY['en-US'];
return bag[key];
}
/**
* 路由查询优先 slug,否则 id
*/
export function resolveSlugOrId(query: QrcodeQuery | null | undefined): string {
if (query == null) {
return '';
}
const slug = trimText(query.slug);
if (slug !== '') {
return slug;
}
return trimText(query.id);
}
function resolvePosterApi(api?: LoadPosterApi): LoadPosterApi {
if (api != null) {
return api;
}
return {
fetchCardQrcodeSvg,
};
}
export function createQrcodeState(): QrcodeState {
return {
slugOrId: '',
svg: '',
url: '',
loading: false,
empty: false,
errorMessage: '',
};
}
/**
* 拉取公开 SVG 海报:可注入 fetchCardQrcodeSvg
*/
export async function loadPoster(
slugOrId: string | null | undefined,
api?: LoadPosterApi
): Promise<LoadPosterResult> {
const key = trimText(slugOrId);
if (key === '') {
return {
svg: '',
url: '',
empty: true,
errorMessage: '',
};
}
try {
const poster = await resolvePosterApi(api).fetchCardQrcodeSvg(key);
const svg = poster != null && poster.svg != null ? String(poster.svg) : '';
const url = poster != null && poster.url != null ? String(poster.url) : '';
return {
svg,
url,
empty: svg === '' && url === '',
errorMessage: '',
};
} catch (err) {
const message =
err instanceof Error
? err.message
: getOmniText(getCurrentLocale(), 'common.error');
return {
svg: '',
url: '',
empty: false,
errorMessage: message,
};
}
}
export async function loadPosterIntoState(
state: QrcodeState,
slugOrId: string | null | undefined,
api?: LoadPosterApi
): Promise<LoadPosterResult> {
state.slugOrId = trimText(slugOrId);
state.loading = true;
state.errorMessage = '';
const result = await loadPoster(state.slugOrId, api);
state.svg = result.svg;
state.url = result.url;
state.empty = result.empty;
state.errorMessage = result.errorMessage;
state.loading = false;
return result;
}
export function applyQrcodeOptions(
state: QrcodeState,
options: QrcodeQuery | null | undefined
): string {
const slugOrId = resolveSlugOrId(options);
state.slugOrId = slugOrId;
return slugOrId;
}
/**
* 主 CTA:复制短链
*/
export function copyPosterUrl(url: string | null | undefined): boolean {
const text = trimText(url);
if (text === '') {
return false;
}
uni.setClipboardData({
data: text,
success: () => {
uni.showToast({
title: getOmniText(getCurrentLocale(), 'portal.copied_link'),
icon: 'none',
});
},
});
return true;
}