对话窗口; 发送文本; 解析WhatsApp信息各类型
parent
ab124d9be3
commit
70fbcae715
@ -0,0 +1,111 @@
|
|||||||
|
export const sentMsgTypeMapped = {
|
||||||
|
text: {
|
||||||
|
type: 'text',
|
||||||
|
contentToSend: (msg) => ({ type: 'text', from: '+8617607730395', to: '', text: { body: msg.text } }),
|
||||||
|
contentToRender: (msg) => ({...msg}),
|
||||||
|
},
|
||||||
|
whatsappTemplate: {
|
||||||
|
type: 'template',
|
||||||
|
contentToSend: (msg) => ({
|
||||||
|
template: {
|
||||||
|
namespace: msg.whatsappTemplate.namespace,
|
||||||
|
language: msg.whatsappTemplate.language,
|
||||||
|
type: msg.whatsappTemplate.type,
|
||||||
|
components: msg.whatsappTemplate.components,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export const whatsappMsgMapped = {
|
||||||
|
'whatsapp.inbound_message.received': {
|
||||||
|
getMsg: (result) => {
|
||||||
|
console.log('whatsapp.inbound_message.received', result);
|
||||||
|
return result?.whatsappInboundMessage || null;
|
||||||
|
},
|
||||||
|
contentToRender: (result) => {
|
||||||
|
console.log( 'whatsapp.inbound_message.received', result);
|
||||||
|
const contentObj = result?.whatsappInboundMessage || result; // debug:
|
||||||
|
return parseRenderMessageItem(contentObj);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export const whatsappMsgTypeMapped = {
|
||||||
|
text: { type: 'text', data: (msg) => ({ text: msg.text.body }) },
|
||||||
|
image: {
|
||||||
|
type: 'photo',
|
||||||
|
data: (msg) => ({
|
||||||
|
data: {
|
||||||
|
uri: msg.image.link,
|
||||||
|
width: 200,
|
||||||
|
height: 200,
|
||||||
|
alt: '',
|
||||||
|
},
|
||||||
|
onOpen: () => {
|
||||||
|
console.log('Open image', msg.image.link);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
sticker: {
|
||||||
|
type: 'photo',
|
||||||
|
data: (msg) => ({
|
||||||
|
data: {
|
||||||
|
uri: msg.sticker.link,
|
||||||
|
width: 150,
|
||||||
|
height: 120,
|
||||||
|
alt: '',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
video: {
|
||||||
|
type: 'video',
|
||||||
|
data: (msg) => ({
|
||||||
|
data: {
|
||||||
|
videoURL: msg.video.link,
|
||||||
|
status: {
|
||||||
|
click: true,
|
||||||
|
loading: 0,
|
||||||
|
download: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
audio: {
|
||||||
|
type: 'audio',
|
||||||
|
data: (msg) => ({
|
||||||
|
data: {
|
||||||
|
audioURL: msg.audio.link,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
'unsupported': { type: 'system', data: (msg) => ({ text: 'Message type is currently not supported.' }) },
|
||||||
|
// 'unsupported': { type: 'text', data: (msg) => ({ text: 'Message type is currently not supported.' }) }
|
||||||
|
// file: 'file',
|
||||||
|
// location: 'location',
|
||||||
|
// contact: 'contact',
|
||||||
|
// 'contact-card': 'contact-card',
|
||||||
|
// 'contact-card-with-photo': 'contact-card-with-photo',
|
||||||
|
// 'contact-card-with-photo-and-label': 'contact-card-with-photo-and-label',
|
||||||
|
};
|
||||||
|
export const parseRenderMessageItem = (msg) => {
|
||||||
|
console.log(msg, '[[[[');
|
||||||
|
return {
|
||||||
|
...(whatsappMsgTypeMapped?.[msg.type]?.data(msg) || {}),
|
||||||
|
id: msg.id,
|
||||||
|
sender: msg.from,
|
||||||
|
type: whatsappMsgTypeMapped?.[msg.type]?.type || 'text',
|
||||||
|
// title: msg.customerProfile.name,
|
||||||
|
date: msg.sendTime,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export const parseRenderMessageList = (messages) => {
|
||||||
|
return messages.map((msg) => {
|
||||||
|
return {
|
||||||
|
...(whatsappMsgTypeMapped?.[msg.type]?.data(msg) || {}),
|
||||||
|
id: msg.id,
|
||||||
|
sender: msg.from,
|
||||||
|
type: whatsappMsgTypeMapped?.[msg.type]?.type || 'text',
|
||||||
|
// title: msg.customerProfile.name,
|
||||||
|
date: msg.sendTime,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
@ -0,0 +1,33 @@
|
|||||||
|
import { createContext, useContext, useEffect, useState } from 'react';
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
import { Popover, Flex, Button } from 'antd';
|
||||||
|
|
||||||
|
const CreatePayment = observer((props) => {
|
||||||
|
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const handleOpenChange = (newOpen) => {
|
||||||
|
setOpen(newOpen);
|
||||||
|
};
|
||||||
|
const onSend = () => {
|
||||||
|
setOpen(false);
|
||||||
|
// todo: send
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Popover
|
||||||
|
// content={<a onClick={hide}>Close</a>}
|
||||||
|
content={
|
||||||
|
<Flex></Flex>
|
||||||
|
}
|
||||||
|
title='🔗付款链接'
|
||||||
|
trigger='click'
|
||||||
|
open={open}
|
||||||
|
onOpenChange={handleOpenChange}>
|
||||||
|
{/* <Button type="primary">Click me</Button> */}
|
||||||
|
{/* <Button type='primary' shape='circle' icon={<></>} size={'large'} /> */}
|
||||||
|
<Button size={'small'}>Book</Button>
|
||||||
|
</Popover>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
export default CreatePayment;
|
@ -0,0 +1,39 @@
|
|||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import { Typography } from 'antd';
|
||||||
|
import { useConversationContext } from '@/stores/ConversationContext';
|
||||||
|
|
||||||
|
const LocalTimeClock = observer((props) => {
|
||||||
|
const { customerOrderProfile: orderInfo } = useConversationContext();
|
||||||
|
|
||||||
|
const [customerDateTime, setCustomerDateTime] = useState();
|
||||||
|
|
||||||
|
// todo: 用dayjs 显示指定时区的时间
|
||||||
|
useEffect(() => {
|
||||||
|
const intervalId = setInterval(() => {
|
||||||
|
// if (customerProfile && customerProfile.timezone) {
|
||||||
|
const date = new Date();
|
||||||
|
const options = {
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric',
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: 'numeric',
|
||||||
|
second: 'numeric',
|
||||||
|
hour12: true,
|
||||||
|
};
|
||||||
|
const formatter = new Intl.DateTimeFormat('cn-ZH', options); // todo:
|
||||||
|
setCustomerDateTime(formatter.format(date));
|
||||||
|
// }
|
||||||
|
}, 1000); // Update every second
|
||||||
|
|
||||||
|
// Cleanup function to clear the interval when the component is unmounted
|
||||||
|
return () => clearInterval(intervalId);
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Typography.Text>{customerDateTime}</Typography.Text>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
export default LocalTimeClock;
|
@ -0,0 +1,63 @@
|
|||||||
|
import { createContext, useContext, useEffect, useState } from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import { Popover, Flex, Button, List, Popconfirm } from 'antd';
|
||||||
|
|
||||||
|
const CreatePayment = observer((props) => {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const handleOpenChange = (newOpen) => {
|
||||||
|
setOpen(newOpen);
|
||||||
|
};
|
||||||
|
const onSend = () => {
|
||||||
|
setOpen(false);
|
||||||
|
// todo: send
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Popover
|
||||||
|
// content={<a onClick={hide}>Close</a>}
|
||||||
|
content={
|
||||||
|
<List
|
||||||
|
className='w-96 h-4/6 overflow-y-auto text-slate-900'
|
||||||
|
itemLayout='horizontal'
|
||||||
|
dataSource={[
|
||||||
|
{ key: 1, title: 'XXX' },
|
||||||
|
{ key: 11, title: 'ZZZZ' },
|
||||||
|
]}
|
||||||
|
renderItem={(item, index) => (
|
||||||
|
<List.Item className=''>
|
||||||
|
<List.Item.Meta
|
||||||
|
className=' text-neutral-800'
|
||||||
|
title={item.title}
|
||||||
|
description={
|
||||||
|
<Flex justify='space-between'>
|
||||||
|
<Button onClick={onSend} size={'small'} type='link' key={'send'}>
|
||||||
|
详细报价
|
||||||
|
</Button>
|
||||||
|
<Flex gap={8}>
|
||||||
|
<Popconfirm title='删除报价信' description='确认要删除报价信吗?' onConfirm={() => {}} onCancel={onSend} okText='Yes' cancelText='No'>
|
||||||
|
<Button size={'small'} type='link' danger key={'send'}>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
<Button onClick={onSend} size={'small'} type='link' key={'send'}>
|
||||||
|
复制
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</List.Item>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
title='📜报价信历史'
|
||||||
|
trigger='click'
|
||||||
|
placement={'left'}
|
||||||
|
open={open}
|
||||||
|
onOpenChange={handleOpenChange}>
|
||||||
|
<Button size={'small'}>报价历史</Button>
|
||||||
|
</Popover>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
export default CreatePayment;
|
Loading…
Reference in New Issue