文件
OmniCard/mpuniapp/pages/owner/card/useCardCases.uts

213 行
5.5 KiB
Plaintext

/**
* 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<OwnerPageData<CardCase>>;
addCase: (data: Partial<CardCase>) => Promise<CardCase>;
updateCase: (data: Partial<CardCase> & { id: string | number }) => Promise<CardCase>;
deleteCase: (id: string | number) => Promise<boolean>;
};
export const defaultCasesApi: CasesApi = {
fetchPage: (query: OwnerPageQuery) => fetchCardCasesPage(query),
addCase: (data: Partial<CardCase>) => addCardCase(data),
updateCase: (data: Partial<CardCase> & { 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<CardCase> | 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<CardCase>): 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<void> {
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<CardCase>,
api: CasesApi = defaultCasesApi
): Promise<boolean> {
const err = validateCaseForm(form);
if (err !== null) {
state.errorMessage = err;
return false;
}
state.saving = true;
state.errorMessage = '';
try {
const payload: Partial<CardCase> = {
...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<boolean> {
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 '';
}
}