feat(frontend): add compact anonymous conversation labels
Build and publish Docker images / Build and publish images (push) Successful in 2m48s

This commit is contained in:
2026-09-15 13:30:49 +08:00
parent 4d684a71eb
commit f79c80519d
6 changed files with 136 additions and 6 deletions
@@ -69,6 +69,81 @@ export const getLastMessage = m => {
);
};
const anonymousContactNames = new Set([
'',
'匿名',
'匿名客户',
'Anonymous Visitor',
'商务通访客',
]);
const firstAttribute = (attributes, ...keys) => {
const value = keys
.map(key => attributes?.[key])
.find(item => typeof item === 'string' && item.trim());
return value?.trim() || '';
};
const contactAttributes = contact => ({
...(contact?.additional_attributes || {}),
...(contact?.additionalAttributes || {}),
...(contact?.custom_attributes || {}),
...(contact?.customAttributes || {}),
});
const visitorLocation = attributes => {
const province = firstAttribute(attributes, 'visitor_province');
const city = firstAttribute(attributes, 'visitor_city');
if (province || city) {
if (!city || !province || city === province || city.startsWith(province)) {
return city || province;
}
return `${province}${city}`;
}
return firstAttribute(attributes, 'swt_ip_location');
};
const shortConversationCode = conversationId => {
const value = String(conversationId ?? '').trim();
if (!/^[1-9]\d*$/.test(value)) {
return '';
}
const numericValue = Number(value);
return Number.isSafeInteger(numericValue)
? numericValue.toString(36).toUpperCase()
: '';
};
/**
* Adds a stable, compact session code only to generated anonymous names.
* The stored contact name remains unchanged.
*/
export const getConversationContactDisplayName = (contact, conversationId) => {
const name = String(contact?.name || '').trim();
const attributes = contactAttributes(contact);
const source = firstAttribute(attributes, 'visitor_name_source');
const isGeneratedName =
anonymousContactNames.has(name) ||
source === 'ip_geolocation' ||
source === 'anonymous_fallback';
if (!isGeneratedName) {
return name;
}
const code = shortConversationCode(conversationId);
if (!code) {
return name || '匿名';
}
const location =
visitorLocation(attributes) ||
(source === 'ip_geolocation' && name.endsWith('客户')
? name.slice(0, -2)
: '');
return location ? `${location}·${code}` : `匿名${code}`;
};
/**
* Filters messages that have been read by the agent.
* @param {Array} messages - The array of messages to filter.