Merge branch 'main' of github.com:hainatravel/global-sales

dev/mobile
Jimmy Liow 2 years ago
commit 107edbf614

@ -0,0 +1,3 @@
import { fetchJSON } from '@/utils/request';
import { API_HOST } from '@/config';

@ -70,6 +70,7 @@ export const sentMsgTypeMapped = {
}),
contentToRender: (msg) => ({
...msg,
whatsapp_msg_type: 'text',
actionId: msg.id,
conversationid: msg.id.split('.')[0],
originText: msg.text,
@ -96,6 +97,7 @@ export const sentMsgTypeMapped = {
contentToRender: (msg) => ({
...msg,
...mediaMsg.contentToRender(msg),
whatsapp_msg_type: 'image',
}),
},
video: {
@ -107,6 +109,7 @@ export const sentMsgTypeMapped = {
contentToRender: (msg) => ({
...msg,
...mediaMsg.contentToRender(msg),
whatsapp_msg_type: 'video',
}),
},
whatsappTemplate: {

@ -26,6 +26,8 @@ const initialConversationState = {
// activeConversations: {}, // 激活的对话的消息列表: { [conversationId]: <messageItem>[] }
// referenceMsg: {},
aliOSSToken: {},
};
const templatesSlice = (set) => ({
@ -282,10 +284,11 @@ export const useConversationStore = create(
// state actions
addError: (error) => set((state) => ({ errors: [...state.errors, error] })),
setInitial: (v) => set({ initialState: v }),
setAliOSSToken: (v) => set({ aliOSSToken: v }),
// side effects
fetchInitialData: async (userId) => {
const { addToConversationList, setTemplates, setInitial, receivedMessageList } = get();
const { addToConversationList, setTemplates, setInitial, receivedMessageList, setAliOSSToken } = get();
const conversationsList = await fetchConversationsList({ opisn: userId });
addToConversationList(conversationsList);

@ -70,7 +70,7 @@ function AuthApp() {
let interval;
if (totalNotify > 0) {
interval = setInterval(() => {
document.title = isTitleVisible ? `🔔🔥【${totalNotify}条新消息】` : '聊天式销售平台';
document.title = isTitleVisible ? `🔔🔥💬${totalNotify}条新消息】` : '聊天式销售平台';
setIsTitleVisible(!isTitleVisible);
}, 500);
} else {

@ -87,6 +87,9 @@ const Conversations = () => {
const handleConversationItemClose = async (item) => {
await fetchConversationItemClose({ conversationid: item.sn, opisn: item.opi_sn });
delConversationitem(item);
if (String(order_sn) === String(item.coli_sn)) {
navigate(`/order/chat`, { replace: true });
}
};
return (
<>

@ -1,21 +1,13 @@
import { createContext, useContext, useEffect, useState } from 'react';
import { useState } from 'react';
import { Upload, Button, message } from 'antd';
import {
SendOutlined,
MessageOutlined,
SmileOutlined,
PictureOutlined,
FileImageOutlined,
CommentOutlined,
UploadOutlined,
CloudUploadOutlined,
FolderAddOutlined,
FilePdfOutlined,
CloseCircleOutlined,
} from '@ant-design/icons';
import useConversationStore from '@/stores/ConversationStore';
import { v4 as uuid } from 'uuid';
import { API_HOST } from '@/config';
const aliOSSHost = `https://haina-sale-system.oss-cn-shenzhen.aliyuncs.com/WAMedia/`;
/**
* image
* ext: ani;bmp;gif;ico;jpe;jpeg;jpg;pcx;png;psd;tga;tif;tiff;wmf
@ -32,26 +24,15 @@ const fileTypes = {
'video': ['3g2','3gp','3gp2','3gpp','amr','amv','asf','avi','bdmv','bik','d2v','divx','drc','dsa','dsm','dsv','evo','f4v','flc','fli','flic','flv','hdmov','ifo','ivf','m1v','m2p','m2t','m2ts','m2v','m4b','m4p','m4v','mkv','mp2v','mp4','mp4v','mpe','mpeg','mpg','mpls','mpv2','mpv4','mov','mts','ogm','ogv','pss','pva','qt','ram','ratdvd','rm','rmm','rmvb','roq','rpm','smil','smk','swf','tp','tpr','ts','vob','vp6','webm','wm','wmp','wmv'],
};
const mockGetOSSData = () => ({
dir: 'user-dir/',
expire: '1577811661',
host: '//haina-sale-system.oss-cn-shenzhen.aliyuncs.com',
accessId: 'LTAI5t8FBxiMYTd4tBSZzVy5',
// todo:
policy: 'eGl4aWhhaGFrdWt1ZGFkYQ==',
signature: 'ZGFob25nc2hhbw==',
});
const ImageUpload = ({ disabled, invokeSendMessage }) => {
const currentConversation = useConversationStore(state => state.currentConversation);
const ImageUpload = ({ disabled }) => {
// const currentConversation = useConversationStore(state => state.currentConversation);
const setComplexMsg = useConversationStore(state => state.setComplexMsg);
const complexMsg = useConversationStore(state => state.complexMsg);
// const aliOSSToken = useConversationStore(state => state.aliOSSToken);
const [uploading, setUploading] = useState(false);
const [OSSData, setOSSData] = useState();
const handleSendImage = (file) => {
console.log(file);
const msgObj = {
type: file.type, // 'photo',
name: file.name,
@ -60,50 +41,29 @@ const ImageUpload = ({ disabled, invokeSendMessage }) => {
id: uuid(),
};
setComplexMsg(msgObj);
// invokeSendMessage(msgObj);
};
const beforeUpload = async (file) => {
console.log('beforeUpload', file);
// 使 FileReader
const reader = new FileReader();
// let ret = true;
//
reader.onload = (event) => {
const previewSrc = event.target.result;
// test: src
const dataUri = `https://images.chinahighlights.com/allpicture/2020/04/9330cd3c78a34c81afd3b1fb.jpg`;
// const dataUri = `https://data.chinahighlights.com/video/CH-homepage-video.mp4`;
const suffix = file.name.slice(file.name.lastIndexOf('.')+1);
const type = Object.keys(fileTypes).find((type) => fileTypes[type].includes(suffix));
const name = file.name;
// ret = type === 'photo';
// const filename = Date.now() + suffix;
// file.url = OSSData.dir + filename;
const dataUri = aliOSSHost + file.name;
handleSendImage({ previewSrc, dataUri, type, suffix, name});
};
// dataURL
reader.readAsDataURL(file);
return file;
// return ret ? file : false;
// if (!OSSData) return false;
// const expire = Number(OSSData.expire) * 1000;
// if (expire < Date.now()) {
// // await init();
// const result = await mockGetOSSData();
// setOSSData(result);
// }
// const suffix = file.name.slice(file.name.lastIndexOf('.'));
// const filename = Date.now() + suffix;
// file.url = OSSData.dir + filename;
// return file;
};
const uploadProps = {
name: 'file',
action: 'https://run.mocky.io/v3/435e224c-44fb-4773-9faf-380c5e6a2188',
// action: OSSData?.host,
action: `${API_HOST}/WAFileUpload`,
headers: {
authorization: 'authorization-text',
'X-Requested-With': null
},
showUploadList: false,
// onChange: handleChange,
@ -115,19 +75,20 @@ const ImageUpload = ({ disabled, invokeSendMessage }) => {
<Upload
{...uploadProps}
onChange={(info) => {
console.log('fileList', info.fileList);
// console.log('fileList', info.fileList);
setUploading(info.file.status === 'uploading');
setComplexMsg({...complexMsg, status: 'loading'})
if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList);
// console.log(info.file, info.fileList);
setComplexMsg({...complexMsg, status: info.file.status})
}
if (info.file.status === 'done') {
// todo:
//
setComplexMsg({...complexMsg, status: info.file.status, data: { ...complexMsg.data, uri: complexMsg.data.dataUri}})
// message.success(`${info.file.name} file uploaded successfully`);
} else if (info.file.status === 'error') {
message.error(`图片添加失败`);
message.error(`添加失败`);
setComplexMsg({ ...complexMsg, status: info.file.status, data: { ...complexMsg.data, uri: ''} })
}
}}
>

@ -22,7 +22,7 @@ import { v4 as uuid } from 'uuid';
import { sentMsgTypeMapped } from '@/lib/msgUtils';
import InputTemplate from './Input/Template';
import InputEmoji from './Input/Emoji';
import InputImageUpload from './Input/ImageUpload';
import InputMediaUpload from './Input/MediaUpload';
import dayjs from 'dayjs';
const InputComposer = () => {
@ -46,6 +46,7 @@ const InputComposer = () => {
const invokeSendMessage = (msgObj) => {
const msgObjMerge = {
sender: 'me',
senderName: 'me',
to: currentConversation.whatsapp_phone_number,
date: new Date(),
status: 'waiting',
@ -107,11 +108,12 @@ const InputComposer = () => {
{complexMsg.id && (
<Flex justify='space-between' className='reply-to bg-gray-100 p-1 rounded-none text-slate-500'>
<div className='pl-2 pr-1 py-1'>
{complexMsg.type === 'photo' && <Image width={100} src={complexMsg.data.uri} />}
{(complexMsg.type === 'photo' && complexMsg.data.uri) && <Image width={100} src={complexMsg.data.uri} />}
{complexMsg.type === 'video' && <FileOutlined className=' text-red-400' />}
{complexMsg.type !== 'photo' && <span className='px-1'>{complexMsg.name}</span>}
{complexMsg.status === 'loading' && <LoadingOutlined className='px-1' />}
{complexMsg.status === 'done' && <CheckCircleOutlined className='px-1 text-primary' />}
{complexMsg.status === 'error' && <><CloseCircleOutlined className='px-1 text-red-400' /> <span>添加失败</span> </>}
</div>
<Button type='text' title='删除' className=' rounded-none text-slate-500' icon={<CloseCircleOutlined />} size={'middle'} onClick={() => setComplexMsg({})} />
</Flex>
@ -137,7 +139,7 @@ const InputComposer = () => {
<Flex gap={4} className='*:text-primary *:rounded-none'>
<InputTemplate key='templates' disabled={!talkabled || textabled} invokeSendMessage={invokeSendMessage} />
<InputEmoji key='emoji' disabled={!textabled} inputEmoji={addEmoji} />
{/* <InputImageUpload key={'addNewPic'} disabled={!textabled} invokeSendMessage={invokeSendMessage} /> */}
<InputMediaUpload key={'addNewMedia'} disabled={!textabled} />
{/* <Button type='text' className='' icon={<YoutubeOutlined />} size={'middle'} />
<Button type='text' className='' icon={<AudioOutlined />} size={'middle'} />
<Button type='text' className='' icon={<FolderAddOutlined />} size={'middle'} />

Loading…
Cancel
Save