Files
nianxx-h5/src/constants/longTextCard.ts
duanshuwen 1a5a2ae6a9 refactor: clean up codebase and add new features
Replace SCSS variable usages with explicit pixel/hex values for consistent styling across all components
Fix broken template syntax including missing class spaces and incorrect closing tags
Migrate constant and API imports to centralized @/constants and @/api modules
Add new utility classes: IdUtils, CallbackUtils, and TimerUtils
Add new chat conversation API endpoints for recent conversations and message lists
Add new Discovery page components (FindTabs, QuickQuestions, CardSwiper) and their styles
Update app store config to use environment variables for base API and WebSocket URLs
Add new selected tab icon assets
2026-05-26 23:50:37 +08:00

174 lines
5.1 KiB
TypeScript

export const LONG_TEXT_KEYS = {
containerType: "container_type",
tag: "tag",
title: "title",
content: "content",
contentSummary: "content_summary",
guideConclusion: "guide_conclusion",
keyFacts: "key_facts",
sceneImage: "scene_image",
checklistOrSteps: "checklist_or_steps",
bestTimeOrPeople: "best_time_or_people",
avoidPitfalls: "avoid_pitfalls",
nextSuggestion: "next_suggestion",
poiDefinition: "poi_definition",
keyHighlights: "key_highlights",
heroImage: "hero_image",
backgroundStory: "background_story",
bestTime: "best_time",
visitSuggestion: "visit_suggestion",
routeSummary: "route_summary",
routeMeta: "route_meta",
routeSteps: "route_steps",
onsiteClues: "onsite_clues",
realtimeNotice: "realtime_notice",
routeWarning: "route_warning",
arrivalNextStep: "arrival_next_step",
photoConclusion: "photo_conclusion",
photoSpots: "photo_spots",
compositionTips: "composition_tips",
phoneSettings: "phone_settings",
lightReminder: "light_reminder",
sampleImage: "sample_image",
components: "components",
checklist: "checklist",
suggest: "suggest",
commodity: "commodity",
actionZone: "action_zone",
};
export const LONG_TEXT_FIELD_CONFIG = [
{ key: LONG_TEXT_KEYS.containerType },
{ key: LONG_TEXT_KEYS.tag },
{ key: LONG_TEXT_KEYS.title },
{ key: LONG_TEXT_KEYS.content },
{ key: LONG_TEXT_KEYS.contentSummary },
{ key: LONG_TEXT_KEYS.guideConclusion },
{ key: LONG_TEXT_KEYS.keyFacts },
{ key: LONG_TEXT_KEYS.sceneImage },
{ key: LONG_TEXT_KEYS.checklistOrSteps },
{ key: LONG_TEXT_KEYS.bestTimeOrPeople },
{ key: LONG_TEXT_KEYS.avoidPitfalls },
{ key: LONG_TEXT_KEYS.nextSuggestion },
{ key: LONG_TEXT_KEYS.poiDefinition },
{ key: LONG_TEXT_KEYS.keyHighlights },
{ key: LONG_TEXT_KEYS.heroImage },
{ key: LONG_TEXT_KEYS.backgroundStory },
{ key: LONG_TEXT_KEYS.bestTime },
{ key: LONG_TEXT_KEYS.visitSuggestion },
{ key: LONG_TEXT_KEYS.routeSummary },
{ key: LONG_TEXT_KEYS.routeMeta },
{ key: LONG_TEXT_KEYS.routeSteps },
{ key: LONG_TEXT_KEYS.onsiteClues },
{ key: LONG_TEXT_KEYS.realtimeNotice },
{ key: LONG_TEXT_KEYS.routeWarning },
{ key: LONG_TEXT_KEYS.arrivalNextStep },
{ key: LONG_TEXT_KEYS.photoConclusion },
{ key: LONG_TEXT_KEYS.photoSpots },
{ key: LONG_TEXT_KEYS.compositionTips },
{ key: LONG_TEXT_KEYS.phoneSettings },
{ key: LONG_TEXT_KEYS.lightReminder },
{ key: LONG_TEXT_KEYS.sampleImage },
{ key: LONG_TEXT_KEYS.components },
{ key: LONG_TEXT_KEYS.checklist },
{ key: LONG_TEXT_KEYS.suggest },
{ key: LONG_TEXT_KEYS.commodity },
{ key: LONG_TEXT_KEYS.actionZone },
];
export const LONG_TEXT_PREVIEW_KEYS = [
LONG_TEXT_KEYS.contentSummary,
LONG_TEXT_KEYS.title,
LONG_TEXT_KEYS.tag,
];
const CONFIGURED_KEYS = LONG_TEXT_FIELD_CONFIG.map((item) => item.key);
export const createLongTextData = () => ({
values: {},
parsedValues: {},
});
const toText = (value) => {
if (value === undefined || value === null) return "";
return typeof value === "string" ? value : String(value);
};
const shouldParseJSON = (raw) => {
if (!raw || typeof raw !== "string") return false;
return /^[\s]*[\[{]/.test(raw);
};
const tryParseJSON = (raw) => {
if (!shouldParseJSON(raw)) {
return { ok: false, value: null };
}
try {
return { ok: true, value: JSON.parse(raw) };
} catch (e) {
return { ok: false, value: null };
}
};
export const appendLongTextChunk = (target, chunk = {}) => {
if (!target || !chunk.contentKey) return target;
const key = String(chunk.contentKey);
const value = toText(chunk.contentValue);
if (!target.values) target.values = {};
if (!target.parsedValues) target.parsedValues = {};
target.values[key] = (target.values[key] || "") + value;
const parsed = tryParseJSON(target.values[key]);
if (parsed.ok) {
target.parsedValues[key] = parsed.value;
} else {
delete target.parsedValues[key];
}
return target;
};
export const getLongTextValue = (data, key) => {
if (!data || !data.values || !key) return "";
return data.values[key] || "";
};
export const getLongTextParsedValue = (data, key, fallback = undefined) => {
if (!data || !data.parsedValues || !key) return fallback;
return Object.prototype.hasOwnProperty.call(data.parsedValues, key)
? data.parsedValues[key]
: fallback;
};
export const getLongTextPreviewText = (data, keys = LONG_TEXT_PREVIEW_KEYS) => {
for (const key of keys) {
const value = getLongTextValue(data, key);
if (value) return value;
}
return "";
};
export const hasLongTextExtraSections = (data, previewKeys = LONG_TEXT_PREVIEW_KEYS) => {
if (!data || !data.values) return false;
return Object.keys(data.values).some((key) => !previewKeys.includes(key));
};
export const getLongTextSections = (data) => {
if (!data || !data.values) return [];
const extraKeys = Object.keys(data.values).filter(
(key) => !CONFIGURED_KEYS.includes(key),
);
return [...CONFIGURED_KEYS, ...extraKeys]
.filter((key) => Object.prototype.hasOwnProperty.call(data.values, key))
.map((key) => ({
contentKey: key,
contentValue: getLongTextValue(data, key),
parsedValue: getLongTextParsedValue(data, key, null),
}));
};