import type { ChannelType } from '@/types/messaging' import type { CustomerStage, OpportunityStage, RiskType, TaskPriority, TaskType } from '@/types/crm' import type { KnowledgeCategory } from '@/types/knowledge' import type { IntentLevel, Sentiment, ValueLevel } from '@/types/common' /** 国家/地区 */ export interface CountryMeta { code: string zh: string en: string flag: string tzOffset: number // 相对 UTC 小时 lang: string } export const COUNTRIES: CountryMeta[] = [ { code: 'PK', zh: '巴基斯坦', en: 'Pakistan', flag: '🇵🇰', tzOffset: 5, lang: 'ur' }, { code: 'BD', zh: '孟加拉国', en: 'Bangladesh', flag: '🇧🇩', tzOffset: 6, lang: 'bn' }, { code: 'AE', zh: '阿联酋', en: 'UAE', flag: '🇦🇪', tzOffset: 4, lang: 'ar' }, { code: 'SA', zh: '沙特阿拉伯', en: 'Saudi Arabia', flag: '🇸🇦', tzOffset: 3, lang: 'ar' }, { code: 'US', zh: '美国', en: 'United States', flag: '🇺🇸', tzOffset: -5, lang: 'en' }, { code: 'GB', zh: '英国', en: 'United Kingdom', flag: '🇬🇧', tzOffset: 0, lang: 'en' }, { code: 'DE', zh: '德国', en: 'Germany', flag: '🇩🇪', tzOffset: 1, lang: 'de' }, { code: 'ES', zh: '西班牙', en: 'Spain', flag: '🇪🇸', tzOffset: 1, lang: 'es' }, { code: 'CN', zh: '中国', en: 'China', flag: '🇨🇳', tzOffset: 8, lang: 'zh' }, ] export function countryMeta(code: string): CountryMeta { const normalized = String(code || '').trim().toUpperCase() const known = COUNTRIES.find((c) => c.code === normalized) if (known) return known if (!/^[A-Z]{2}$/.test(normalized)) { return { code: '', zh: '国家待确认', en: 'Country not confirmed', flag: '🌐', tzOffset: Number.NaN, lang: '' } } const flag = String.fromCodePoint( ...[...normalized].map((character) => 127397 + character.charCodeAt(0)), ) const zh = new Intl.DisplayNames(['zh-CN'], { type: 'region' }).of(normalized) || normalized const en = new Intl.DisplayNames(['en'], { type: 'region' }).of(normalized) || normalized return { code: normalized, zh, en, flag, tzOffset: Number.NaN, lang: '' } } /** 行业 */ export const INDUSTRIES = ['服装纺织', '玻璃制品', '3C电子', '家居用品', '通用外贸'] /** 客户阶段 */ export const CUSTOMER_STAGES: { value: CustomerStage; label: string; color: string }[] = [ { value: 'initial', label: '初次咨询', color: 'bg-sky-100 text-sky-700' }, { value: 'comparing', label: '价格比较', color: 'bg-amber-100 text-amber-700' }, { value: 'sample', label: '样品确认', color: 'bg-violet-100 text-violet-700' }, { value: 'custom', label: '定制沟通', color: 'bg-cyan-100 text-cyan-700' }, { value: 'closing', label: '成交推进', color: 'bg-emerald-100 text-emerald-700' }, { value: 'fulfillment', label: '履约跟踪', color: 'bg-teal-100 text-teal-700' }, { value: 'aftersales', label: '售后处理', color: 'bg-orange-100 text-orange-700' }, { value: 'repurchase', label: '复购培育', color: 'bg-rose-100 text-rose-700' }, ] export function customerStageMeta(stage: CustomerStage) { return CUSTOMER_STAGES.find((s) => s.value === stage) ?? CUSTOMER_STAGES[0] } /** 商机阶段 */ export const OPPORTUNITY_STAGES: { value: OpportunityStage; label: string; color: string }[] = [ { value: 'new', label: '新询盘', color: 'bg-sky-100 text-sky-700' }, { value: 'requirement', label: '需求确认', color: 'bg-blue-100 text-blue-700' }, { value: 'quoting', label: '报价中', color: 'bg-amber-100 text-amber-700' }, { value: 'sample', label: '样品沟通', color: 'bg-violet-100 text-violet-700' }, { value: 'custom', label: '定制确认', color: 'bg-cyan-100 text-cyan-700' }, { value: 'negotiation', label: '商务谈判', color: 'bg-orange-100 text-orange-700' }, { value: 'pending-deal', label: '待成交', color: 'bg-emerald-100 text-emerald-700' }, { value: 'won', label: '已成交', color: 'bg-green-100 text-green-700' }, { value: 'fulfillment', label: '履约中', color: 'bg-teal-100 text-teal-700' }, { value: 'aftersales', label: '售后中', color: 'bg-yellow-100 text-yellow-700' }, { value: 'repurchase', label: '复购培育', color: 'bg-rose-100 text-rose-700' }, { value: 'lost', label: '已流失', color: 'bg-gray-200 text-gray-500' }, ] export function opportunityStageMeta(stage: OpportunityStage) { return OPPORTUNITY_STAGES.find((s) => s.value === stage) ?? OPPORTUNITY_STAGES[0] } /** 意向等级 */ export const INTENT_LEVELS: { value: IntentLevel; label: string; color: string; range: string }[] = [ { value: 'high', label: '高价值', color: 'bg-emerald-100 text-emerald-700', range: '80—100' }, { value: 'medium-high', label: '中高价值', color: 'bg-teal-100 text-teal-700', range: '60—79' }, { value: 'medium', label: '中等价值', color: 'bg-amber-100 text-amber-700', range: '40—59' }, { value: 'low', label: '低价值', color: 'bg-gray-100 text-gray-500', range: '0—39' }, ] export function intentLevelOf(score: number): IntentLevel { if (score >= 80) return 'high' if (score >= 60) return 'medium-high' if (score >= 40) return 'medium' return 'low' } export function intentLevelMeta(level: IntentLevel) { return INTENT_LEVELS.find((l) => l.value === level) ?? INTENT_LEVELS[3] } export const VALUE_LEVELS: { value: ValueLevel; label: string; color: string }[] = [ { value: 'A', label: 'A级(重点)', color: 'bg-emerald-100 text-emerald-700' }, { value: 'B', label: 'B级(优质)', color: 'bg-teal-100 text-teal-700' }, { value: 'C', label: 'C级(普通)', color: 'bg-amber-100 text-amber-700' }, { value: 'D', label: 'D级(观察)', color: 'bg-gray-100 text-gray-500' }, ] /** 情绪状态 */ export const SENTIMENTS: { value: Sentiment; label: string; color: string; emoji: string }[] = [ { value: 'positive', label: '积极', color: 'text-emerald-600', emoji: '😊' }, { value: 'neutral-positive', label: '中性偏积极', color: 'text-teal-600', emoji: '🙂' }, { value: 'neutral', label: '中性', color: 'text-gray-500', emoji: '😐' }, { value: 'negative', label: '消极', color: 'text-amber-600', emoji: '😟' }, { value: 'angry', label: '不满', color: 'text-red-600', emoji: '😠' }, ] export function sentimentMeta(s: Sentiment) { return SENTIMENTS.find((x) => x.value === s) ?? SENTIMENTS[2] } /** 风险等级 */ export const RISK_LEVELS = [ { value: 'low', label: '低', color: 'bg-gray-100 text-gray-600', dot: 'bg-gray-400' }, { value: 'medium', label: '中', color: 'bg-amber-100 text-amber-700', dot: 'bg-amber-500' }, { value: 'high', label: '高', color: 'bg-orange-100 text-orange-700', dot: 'bg-orange-500' }, { value: 'urgent', label: '紧急', color: 'bg-red-100 text-red-700', dot: 'bg-red-500' }, ] as const export function riskLevelMeta(level: string) { return RISK_LEVELS.find((l) => l.value === level) ?? RISK_LEVELS[0] } /** 风险类型 */ export const RISK_TYPES: { value: RiskType; label: string }[] = [ { value: 'negative-sentiment', label: '客户负面情绪' }, { value: 'dispute', label: '潜在交易纠纷' }, { value: 'price-objection', label: '价格异议' }, { value: 'delivery', label: '交期风险' }, { value: 'logistics', label: '物流风险' }, { value: 'complaint', label: '售后投诉' }, { value: 'culture', label: '文化敏感表达' }, { value: 'religion', label: '宗教敏感表达' }, { value: 'follow-up-delay', label: '高价值客户久未跟进' }, { value: 'churn', label: '客户可能流失' }, { value: 'task-overdue', label: '跟进任务逾期' }, { value: 'account-abnormal', label: '异常账号登录' }, ] export function riskTypeLabel(type: RiskType): string { return RISK_TYPES.find((t) => t.value === type)?.label ?? type } /** 跟进任务类型 */ export const TASK_TYPES: { value: TaskType; label: string }[] = [ { value: 'quote', label: '发送报价' }, { value: 'material', label: '发送资料' }, { value: 'sample', label: '样品确认' }, { value: 'custom', label: '定制沟通' }, { value: 'revisit', label: '回访客户' }, { value: 'urge', label: '催单跟进' }, { value: 'logistics', label: '物流跟进' }, { value: 'aftersales', label: '售后处理' }, { value: 'repurchase', label: '复购提醒' }, { value: 'custom-task', label: '自定义任务' }, ] export function taskTypeLabel(type: TaskType): string { return TASK_TYPES.find((t) => t.value === type)?.label ?? type } export const TASK_PRIORITIES: { value: TaskPriority; label: string; color: string }[] = [ { value: 'high', label: '高', color: 'bg-red-100 text-red-700' }, { value: 'medium', label: '中', color: 'bg-amber-100 text-amber-700' }, { value: 'low', label: '低', color: 'bg-gray-100 text-gray-600' }, ] export function taskPriorityMeta(p: TaskPriority) { return TASK_PRIORITIES.find((x) => x.value === p) ?? TASK_PRIORITIES[1] } /** 渠道元信息 */ export const CHANNEL_META: Record = { whatsapp: { name: 'WhatsApp', color: 'text-emerald-600', bg: 'bg-emerald-50', desc: '海外即时沟通主渠道' }, telegram: { name: 'Telegram', color: 'text-sky-600', bg: 'bg-sky-50', desc: '中东/中亚客户常用' }, messenger: { name: 'Messenger', color: 'text-blue-600', bg: 'bg-blue-50', desc: 'Facebook 私信咨询' }, email: { name: '企业邮箱', color: 'text-gray-600', bg: 'bg-gray-100', desc: '正式商务邮件往来' }, gmail: { name: 'Gmail', color: 'text-red-500', bg: 'bg-red-50', desc: 'Google 邮箱账号' }, outlook: { name: 'Outlook', color: 'text-blue-500', bg: 'bg-blue-50', desc: '微软邮箱账号' }, webform: { name: '独立站表单', color: 'text-violet-600', bg: 'bg-violet-50', desc: '独立站询盘表单' }, website: { name: '官网咨询按钮', color: 'text-teal-600', bg: 'bg-teal-50', desc: '官网在线客服入口' }, landing: { name: '广告落地页', color: 'text-amber-600', bg: 'bg-amber-50', desc: '广告投放线索页面' }, social: { name: '社交媒体主页', color: 'text-pink-600', bg: 'bg-pink-50', desc: '社媒主页私信与留言' }, exhibition: { name: '展会二维码', color: 'text-cyan-600', bg: 'bg-cyan-50', desc: '展会扫码留资' }, api: { name: 'API 接口', color: 'text-slate-600', bg: 'bg-slate-100', desc: '开放 API 对接自有系统' }, webhook: { name: 'Webhook', color: 'text-indigo-600', bg: 'bg-indigo-50', desc: '事件推送到自有服务' }, } /** 回复语气 */ export const REPLY_TONES = [ { value: 'professional', label: '专业正式' }, { value: 'friendly', label: '友好自然' }, { value: 'concise', label: '简洁直接' }, { value: 'negotiation', label: '商务谈判' }, { value: 'comfort', label: '售后安抚' }, { value: 'urge', label: '催单跟进' }, ] /** 翻译场景 */ export const TRANSLATE_SCENARIOS = [ { value: 'chat', label: '即时聊天' }, { value: 'email', label: '商务邮件' }, { value: 'product', label: '产品介绍' }, { value: 'quote', label: '报价沟通' }, { value: 'sample', label: '样品沟通' }, { value: 'custom', label: '定制要求' }, { value: 'logistics', label: '物流说明' }, { value: 'contract', label: '合同沟通' }, { value: 'aftersales', label: '售后处理' }, ] /** 知识库分类 */ export const KNOWLEDGE_CATEGORIES: { value: KnowledgeCategory; label: string }[] = [ { value: 'product', label: '产品资料' }, { value: 'pricing', label: '价格规则' }, { value: 'moq', label: 'MOQ规则' }, { value: 'customization', label: '定制说明' }, { value: 'logistics', label: '物流政策' }, { value: 'payment', label: '付款方式' }, { value: 'aftersales', label: '售后政策' }, { value: 'faq', label: 'FAQ' }, { value: 'company', label: '企业介绍' }, { value: 'certification', label: '产品认证' }, { value: 'success-reply', label: '历史成功回复' }, { value: 'terminology', label: '行业术语' }, { value: 'culture', label: '文化注意事项' }, ] export function knowledgeCategoryLabel(c: KnowledgeCategory): string { return KNOWLEDGE_CATEGORIES.find((x) => x.value === c)?.label ?? c } /** 客户常用标签 */ export const CUSTOMER_TAGS = [ '重点客户', '大客户潜力', '价格敏感', '交期敏感', '需要样品', '定制需求', '复购客户', '展会客户', '老客户', '高风险', '斋月注意', '决策人直联', ] /** AI 推荐动作 */ export const NEXT_ACTIONS = [ '发送报价', '补充资料', '发送认证文件', '确认样品', '询问采购时间', '回访客户', '提醒重点跟进', '售后安抚', '复购提醒', ] /** 向导用常用语言清单(中文名) */ export const LANGUAGES_LIST = [ '中文', '英语', '阿拉伯语', '乌尔都语', '孟加拉语', '西班牙语', '葡萄牙语', '俄语', '法语', '德语', '土耳其语', '越南语', '印尼语', '日语', '韩语', ] /** 企业主营产品选项 */ export const PRODUCTS = [ '双层玻璃杯 350ml', '高硼硅玻璃杯 500ml', '定制Logo玻璃水杯', '玻璃储物罐套装', '男士纯棉T恤', '女士针织开衫', '运动速干POLO衫', 'TWS蓝牙耳机', '65W氮化镓充电器', '智能手表', '北欧棉麻四件套', 'ins风陶瓷餐具套装', ]