From 714718053c6c21a87ee3908fa0c590582d8b8fed Mon Sep 17 00:00:00 2001 From: Lei OT Date: Tue, 9 Apr 2024 16:31:35 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=9C=A8=E6=B6=88=E6=81=AF=E7=AA=97?= =?UTF-8?q?=E5=8F=A3=E6=89=93=E5=BC=80=E6=96=B0=E4=BC=9A=E8=AF=9D,=20?= =?UTF-8?q?=E5=B7=B2=E5=AD=98=E5=9C=A8=E5=88=99=E5=88=87=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/channel/whatsappUtils.js | 45 ++++++++++++++ .../Online/ConversationsNewItem.jsx | 60 +++++++++++++++---- .../Conversations/Online/MessagesList.jsx | 23 ++++++- 3 files changed, 116 insertions(+), 12 deletions(-) diff --git a/src/channel/whatsappUtils.js b/src/channel/whatsappUtils.js index 7698c10..4ddc5ce 100644 --- a/src/channel/whatsappUtils.js +++ b/src/channel/whatsappUtils.js @@ -672,3 +672,48 @@ export const handleNotification = (title, _options) => { }; } }; + +/** + * WhatsApp 国际号码 + * + * - Make sure to remove any leading 0s or special calling codes. + * - All phone numbers in Argentina (country code "54") should have a "9" between the country code and area code. The prefix "15" must be removed so the final number will have 13 digits total: +54 9 XXX XXX XXXX + * - Phone numbers in Mexico (country code "52") need to have "1" after "+52", even if they're Nextel numbers. + */ +export const phoneNumberToWAID = (input) => { + // Remove any non-digit characters except '+' + const cleanedInput = input.replace(/[^\d+]/g, ''); + + // Check if the number starts with a valid country code + const countryCode = cleanedInput.slice(0, 2); + const isArgentina = countryCode === '54'; + const isMexico = countryCode === '52'; + + if (!isArgentina && !isMexico) { + return cleanedInput; // Return the cleaned input as is + } + + // Remove leading 0s and special calling codes + let formattedNumber = cleanedInput.replace(/^0+/, ''); + + if (isArgentina) { + // Remove the prefix "15" if present + // formattedNumber = formattedNumber.replace(/^15/, ''); + formattedNumber = formattedNumber.replace(/^54 ?15/, '54'); + // Remove leading '0' after country code + formattedNumber = formattedNumber.replace(/^54 ?0/, '54'); + + // Insert "9" between the country code and area code + formattedNumber = `54 9 ${formattedNumber.slice(2)}`; + } else if (isMexico) { + // Remove leading '0' after country code + formattedNumber = formattedNumber.replace(/^52 ?0/, '52'); + // Insert "1" after the country code + formattedNumber = `52 1 ${formattedNumber.slice(2)}`; + } + + // Remove any non-digit characters except '+' + formattedNumber = formattedNumber.replace(/[^\d+]/g, ''); + + return formattedNumber; +} diff --git a/src/views/Conversations/Online/ConversationsNewItem.jsx b/src/views/Conversations/Online/ConversationsNewItem.jsx index 70c4e7f..2f0106e 100644 --- a/src/views/Conversations/Online/ConversationsNewItem.jsx +++ b/src/views/Conversations/Online/ConversationsNewItem.jsx @@ -1,22 +1,57 @@ import { useState, useEffect } from 'react'; import { Form, Input, Modal } from 'antd'; -import { isEmpty } from '@/utils/commons'; +import { isEmpty, pick } from '@/utils/commons'; +import useConversationStore from '@/stores/ConversationStore'; +import { phoneNumberToWAID } from '@/channel/whatsappUtils'; export const ConversationItemForm = ({ initialValues, onFormInstanceReady }) => { + const [currentConversation] = useConversationStore((state) => [state.currentConversation]); + const fromCurrent = initialValues?.is_current_order ? pick(currentConversation, ['coli_sn', 'coli_id', 'opi_sn']) : {}; const [form] = Form.useForm(); + const [formatPhone, setFormatPhone] = useState(''); + const [formatVisible, setFormatVisible] = useState(false); + useEffect(() => { onFormInstanceReady(form); + setFormatPhone(phoneNumberToWAID(initialValues.phone_number)); }, []); + + useEffect(() => { + form.setFieldValue('wa_id', formatPhone); + return () => {}; + }, [formatPhone]); + + const onValuesChange = (changeValues, allValues) => { + if ('phone_number' in changeValues) { + const _t = phoneNumberToWAID(changeValues.phone_number); + setFormatPhone(_t); + setFormatVisible(_t !== changeValues.phone_number); + } + }; return ( -
- + + - {/* - - */} - - + {/* hidden */} + + + + + {/* @@ -29,13 +64,16 @@ export const ConversationItemFormModal = ({ open, onCreate, onCancel, initialVal return ( { onCancel(); formInstance?.resetFields();}} + onCancel={() => { + onCancel(); + formInstance?.resetFields(); + }} destroyOnClose onOk={async () => { try { diff --git a/src/views/Conversations/Online/MessagesList.jsx b/src/views/Conversations/Online/MessagesList.jsx index 61ddefc..6837c67 100644 --- a/src/views/Conversations/Online/MessagesList.jsx +++ b/src/views/Conversations/Online/MessagesList.jsx @@ -5,6 +5,7 @@ import { DownOutlined, LoadingOutlined } from '@ant-design/icons'; import { useShallow } from 'zustand/react/shallow'; import useConversationStore from '@/stores/ConversationStore'; import { groupBy, isEmpty, } from '@/utils/commons'; +import ConversationsNewItem from './ConversationsNewItem'; const MessagesList = ({ messages, handlePreview, reference, longListLoading, getMoreMessages, shouldScrollBottom, loadNextPage, handleContactClick, ...props }) => { @@ -50,13 +51,16 @@ const MessagesList = ({ messages, handlePreview, reference, longListLoading, get buttonsArr = componentsObj?.buttons?.reduce((r, c) => r.concat(c.buttons), []); } - const parts = str.split(/(https?:\/\/[^\s]+|\p{Emoji_Presentation})/gmu).filter((s) => s !== ''); + const parts = str.split(/(https?:\/\/[^\s]+|\p{Emoji_Presentation}|\d{4,})/gmu).filter((s) => s !== ''); const links = str.match(/https?:\/\/[\S]+/gi) || []; + const numbers = str.match(/\d{4,}/g) || []; const emojis = str.match(/([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g) || []; const extraClass = isEmpty(emojis) ? '' : ''; const objArr = parts.reduce((prev, curr, index) => { if (links.includes(curr)) { prev.push({ type: 'link', key: curr }); + } else if (numbers.includes(curr)) { + prev.push({ type: 'number', key: curr }); } else if (emojis.includes(curr)) { prev.push({ type: 'emoji', key: curr }); } else { @@ -84,6 +88,13 @@ const MessagesList = ({ messages, handlePreview, reference, longListLoading, get {part.key} ); + } else if (part.type === 'number') { + return ( + {setNewChatModalVisible(true); + setNewChatFormValues(prev => ({...prev, phone_number: part.key, is_current_order: true, }))}}> + {part.key} + + ); } else { // if (part.type === 'emoji') return part.key; @@ -123,6 +134,15 @@ const MessagesList = ({ messages, handlePreview, reference, longListLoading, get )); + const [newChatModalVisible, setNewChatModalVisible] = useState(false); + const [newChatFormValues, setNewChatFormValues] = useState({}); + const handleNewChat = async (values) => { + const newContact = { wa_id: values.wa_id }; + await handleContactClick([newContact]); + setNewChatModalVisible(false); + } + + return (
@@ -188,6 +208,7 @@ const MessagesList = ({ messages, handlePreview, reference, longListLoading, get ))}
); };