feat: 长文本组件的对接调试
This commit is contained in:
@@ -1,28 +1,34 @@
|
||||
// 简单的流式数据管理器:开启流、更新流、订阅流、关闭流
|
||||
const streams = {};
|
||||
|
||||
function openStream(id, initial = '', finished = false) {
|
||||
if (!id) return;
|
||||
streams[id] = streams[id] || { text: '', finished: false, subs: new Set() };
|
||||
streams[id].text = initial || '';
|
||||
streams[id].finished = !!finished;
|
||||
// notify existing subscribers
|
||||
streams[id].subs.forEach((cb) => cb(streams[id].text, streams[id].finished));
|
||||
function notify(stream) {
|
||||
stream.subs.forEach((cb) => cb(stream.text, stream.finished, stream.payload));
|
||||
}
|
||||
|
||||
function updateStream(id, text, finished = false) {
|
||||
function openStream(id, initial = '', finished = false, payload = null) {
|
||||
if (!id) return;
|
||||
streams[id] = streams[id] || { text: '', finished: false, payload: null, subs: new Set() };
|
||||
streams[id].text = initial || '';
|
||||
streams[id].finished = !!finished;
|
||||
streams[id].payload = payload || null;
|
||||
// notify existing subscribers
|
||||
notify(streams[id]);
|
||||
}
|
||||
|
||||
function updateStream(id, text, finished = false, payload = null) {
|
||||
if (!id || !streams[id]) return;
|
||||
streams[id].text = text || '';
|
||||
streams[id].finished = !!finished;
|
||||
streams[id].subs.forEach((cb) => cb(streams[id].text, streams[id].finished));
|
||||
streams[id].payload = payload || null;
|
||||
notify(streams[id]);
|
||||
}
|
||||
|
||||
function subscribe(id, cb) {
|
||||
if (!id) return () => {};
|
||||
streams[id] = streams[id] || { text: '', finished: false, subs: new Set() };
|
||||
streams[id] = streams[id] || { text: '', finished: false, payload: null, subs: new Set() };
|
||||
streams[id].subs.add(cb);
|
||||
// send current snapshot immediately
|
||||
cb(streams[id].text, streams[id].finished);
|
||||
cb(streams[id].text, streams[id].finished, streams[id].payload);
|
||||
return () => {
|
||||
streams[id] && streams[id].subs.delete(cb);
|
||||
// 移除空流
|
||||
@@ -34,13 +40,13 @@ function subscribe(id, cb) {
|
||||
|
||||
function closeStream(id) {
|
||||
if (!id || !streams[id]) return;
|
||||
streams[id].subs.forEach((cb) => cb(streams[id].text, true));
|
||||
streams[id].subs.forEach((cb) => cb(streams[id].text, true, streams[id].payload));
|
||||
delete streams[id];
|
||||
}
|
||||
|
||||
function getSnapshot(id) {
|
||||
if (!id || !streams[id]) return { text: '', finished: false };
|
||||
return { text: streams[id].text, finished: streams[id].finished };
|
||||
if (!id || !streams[id]) return { text: '', finished: false, payload: null };
|
||||
return { text: streams[id].text, finished: streams[id].finished, payload: streams[id].payload };
|
||||
}
|
||||
|
||||
export default {
|
||||
|
||||
115
src/utils/longTextCard.js
Normal file
115
src/utils/longTextCard.js
Normal file
@@ -0,0 +1,115 @@
|
||||
export const LONG_TEXT_KEYS = {
|
||||
tag: "tag",
|
||||
title: "title",
|
||||
content: "content",
|
||||
checklist: "checklist",
|
||||
suggest: "suggest",
|
||||
commodity: "commodity",
|
||||
actionZone: "action_zone",
|
||||
};
|
||||
|
||||
export const LONG_TEXT_FIELD_CONFIG = [
|
||||
{ key: LONG_TEXT_KEYS.tag },
|
||||
{ key: LONG_TEXT_KEYS.title },
|
||||
{ key: LONG_TEXT_KEYS.content },
|
||||
{ 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.content,
|
||||
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),
|
||||
}));
|
||||
};
|
||||
Reference in New Issue
Block a user