/** * OmniCard AI (CRMmp) - 产品相册与标杆案例移动端业务逻辑驱动层 * 严格遵循 uts 强类型契约与 AGENTS.md 规范 */ import { CardCase, OwnerPageData, OwnerPageQuery } from '../../../common/types.uts'; import { fetchCardCasesPage, addCardCase, updateCardCase, deleteCardCase, } from '../../../common/api.uts'; import { getCurrentLocale, getOmniText } from '../../../common/locale.uts'; export const PRESET_CASE_METRICS: string[] = [ '+320% ROI', '+150% 留资率', '45k+ 海外线索', '2M+ 全球曝光', 'Top 1 细分类目', ]; export type CasesApi = { fetchPage: (query: OwnerPageQuery) => Promise>; addCase: (data: Partial) => Promise; updateCase: (data: Partial & { id: string | number }) => Promise; deleteCase: (id: string | number) => Promise; }; export const defaultCasesApi: CasesApi = { fetchPage: (query: OwnerPageQuery) => fetchCardCasesPage(query), addCase: (data: Partial) => addCardCase(data), updateCase: (data: Partial & { id: string | number }) => updateCardCase(data), deleteCase: (id: string | number) => deleteCardCase(id), }; export type CasesState = { cardId: string | number; list: CardCase[]; loading: boolean; empty: boolean; errorMessage: string; drawerVisible: boolean; editingCase: Partial | null; saving: boolean; }; export function createCasesState(cardId: string | number): CasesState { return { cardId, list: [], loading: false, empty: false, errorMessage: '', drawerVisible: false, editingCase: null, saving: false, }; } export function validateCaseForm(form: Partial): string | null { const title = form.title != null ? form.title.trim() : ''; if (title === '') { return '请输入案例或产品标题'; } if (title.length > 150) { return '标题长度不能超过 150 个字符'; } return null; } export async function loadCases( state: CasesState, api: CasesApi = defaultCasesApi ): Promise { state.loading = true; state.errorMessage = ''; try { const res = await api.fetchPage({ page: 1, size: 50, cardId: state.cardId, }); const items = res.list != null ? res.list : []; state.list = items; state.empty = items.length === 0; } catch (err: any) { state.errorMessage = err.message || '加载案例列表失败'; } finally { state.loading = false; } } export async function saveCase( state: CasesState, form: Partial, api: CasesApi = defaultCasesApi ): Promise { const err = validateCaseForm(form); if (err !== null) { state.errorMessage = err; return false; } state.saving = true; state.errorMessage = ''; try { const payload: Partial = { ...form, cardId: state.cardId, title: form.title!.trim(), }; if (form.id != null) { await api.updateCase({ ...payload, id: form.id, }); } else { await api.addCase(payload); } state.drawerVisible = false; state.editingCase = null; await loadCases(state, api); return true; } catch (err: any) { state.errorMessage = err.message || '保存案例失败'; return false; } finally { state.saving = false; } } export async function deleteCase( state: CasesState, id: string | number, api: CasesApi = defaultCasesApi ): Promise { state.saving = true; state.errorMessage = ''; try { const ok = await api.deleteCase(id); if (ok) { await loadCases(state, api); return true; } return false; } catch (err: any) { state.errorMessage = err.message || '删除案例失败'; return false; } finally { state.saving = false; } } export type CasesCopyKey = | 'title' | 'subtitle' | 'addBtn' | 'editBtn' | 'deleteBtn' | 'emptyTitle' | 'emptyDesc' | 'fieldTitle' | 'fieldClient' | 'fieldDuration' | 'fieldMetrics' | 'fieldDesc' | 'fieldCover' | 'saveBtn' | 'cancelBtn'; export function resolveCasesText(key: CasesCopyKey): string { const locale = getCurrentLocale(); const zh = locale === 'zh-CN'; switch (key) { case 'title': return zh ? '产品相册与标杆案例' : 'Portfolio & Case Studies'; case 'subtitle': return zh ? '随时维护产品画廊与标杆案例,在微官网中向全球买家展现硬核实力' : 'Showcase your products and case studies on your micro-site.'; case 'addBtn': return zh ? '新增产品案例' : 'Add Case Study'; case 'editBtn': return zh ? '编辑' : 'Edit'; case 'deleteBtn': return zh ? '删除' : 'Delete'; case 'emptyTitle': return zh ? '暂无产品案例' : 'No Cases Yet'; case 'emptyDesc': return zh ? '点击下方按钮,拍照或上传您的首个产品相册与案例' : 'Tap below to add your first product showcase or case study.'; case 'fieldTitle': return zh ? '案例/产品名称' : 'Title'; case 'fieldClient': return zh ? '合作客商/品牌 (选填)' : 'Client / Brand'; case 'fieldDuration': return zh ? '项目周期 (选填)' : 'Timeline'; case 'fieldMetrics': return zh ? '量化成效标签' : 'Key Metrics Tag'; case 'fieldDesc': return zh ? '方案成果简述' : 'Overview'; case 'fieldCover': return zh ? '产品封面与相册图片' : 'Cover & Photos'; case 'saveBtn': return zh ? '保存案例' : 'Save Case'; case 'cancelBtn': return zh ? '取消' : 'Cancel'; default: return ''; } }