You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Global-sales/src/views/orders/Follow.jsx

232 lines
9.6 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import useAuthStore from '@/stores/AuthStore'
import { pick } from '@/utils/commons'
import { UnorderedListOutlined, LeftOutlined } from '@ant-design/icons'
import { Flex, Segmented, Tree, Typography, Layout, Splitter, Button, Tooltip, Badge } from 'antd'
import { useEffect, useMemo, useState, useRef } from 'react'
import EmailDetailInline from '../Conversations/Online/Components/EmailDetailInline'
import OrderProfile from '@/components/OrderProfile'
import Mailbox from './components/Mailbox'
import useConversationStore from '@/stores/ConversationStore';
import { MailboxDirIcon } from './components/MailboxDirIcon'
import { useVisibilityState } from '@/hooks/useVisibilityState'
const deptMap = new Map([
['1', 'CH'], // CH直销组
['2', 'CH大客户组'],
['7', '市场推广'],
['8', '德语市场'],
['9', '日语市场'],
['10', '商旅市场'],
['11', '法语市场'],
['12', '西语市场'],
['13', '英文在线组'],
['14', '商务Biztravel'],
['15', 'CH产品'],
['16', 'APP移动项目组'],
['17', 'ChinaTravel组'],
['18', 'CT市场'],
['20', '俄语市场'],
['21', '意语市场'],
['22', '爱游网'],
['23', '三峡站'],
['24', '桂林站'],
['25', '上海站'],
['26', '北京站'],
['27', '西藏站'],
['28', 'AH'], // AH亚洲项目组
['29', 'DMC地接组'],
['30', 'Trippest项目组'], //
['31', '花梨鹰'],
['32', 'Daytours板块'],
['33', 'GH'], // GH项目组
['34', 'trippest网站'],
['35', 'newsletter营销'],
])
function Follow() {
const [collapsed, setCollapsed] = useState(true)
const mailboxTreeRef = useRef(null);
const [treeHeight, setTreeHeight] = useState(500);
const [loginUser, isPermitted] = useAuthStore((state) => [state.loginUser, state.isPermitted])
const { accountList } = loginUser
const accountListDEIMapped = useMemo(() => accountList.reduce((a, c) => ({ ...a, [c.OPI_DEI_SN]: c }), {}), [accountList])
const accountDEI = useMemo(() => {
return accountList.map((ele) => ({ key: ele.OPI_DEI_SN, value: ele.OPI_DEI_SN, label: deptMap.get(`${ele.OPI_DEI_SN}`) }))
}, [accountList])
const [getOPIEmailDir] = useConversationStore(state => [state.getOPIEmailDir]);
const [currentMailboxDEI, setCurrentMailboxDEI, mailboxNestedDirsActive] = useConversationStore(state => [state.currentMailboxDEI, state.setCurrentMailboxDEI, state.mailboxNestedDirsActive]);
const [currentMailboxOPI, setCurrentMailboxOPI] = useConversationStore(state => [state.currentMailboxOPI, state.setCurrentMailboxOPI]);
const [mailboxActiveNode, setMailboxActiveNode] = useConversationStore(state => [state.mailboxActiveNode, state.setMailboxActiveNode]);
const [activeEmailId, setActiveEmailId] = useConversationStore(state => [state.mailboxActiveMAI, state.setMailboxActiveMAI]);
const [mailboxActiveCOLI, setMailboxActiveCOLI] = useConversationStore(state => [state.mailboxActiveCOLI, state.setMailboxActiveCOLI]);
const computedBreadcrumb = useMemo(() => {
const { title, iconIndex, parentTitle, parentIconIndex } = mailboxActiveNode
const x = [
{ title: parentTitle, iconIndex: parentIconIndex },
{ title, iconIndex },
].filter((ele) => ele.title)
return x
}, [mailboxActiveNode.VKey])
const [expandTree, setExpandTree] = useState([])
const handleSwitchAccount = (value) => {
setActiveEmailId(0);
// setExpandTree([]);
setCurrentMailboxDEI(value)
const opi = accountListDEIMapped[value].OPI_SN
getOPIEmailDir(opi)
setCurrentMailboxOPI(opi);
}
const handleTreeSelectGetMails = (selectedKeys, { node }) => {
// console.info('selectedTreeKeys: ', node)
const treeNode = pick(node, ['key', 'parent', 'iconIndex', 'getMails', 'title', 'parentTitle', 'parentIconIndex' ]);
const { COLI_SN, VKey, VParent, ApplyDate, OrderSourceType, IsTrue } = node?._raw || {}
if (VKey && !(!IsTrue && !COLI_SN)) {
setMailboxActiveNode({...treeNode, ...node._raw, key: treeNode.key, OPI_SN: currentMailboxOPI});
setActiveEmailId(0);
setMailboxActiveCOLI(COLI_SN);
} else {
const _expandTree = expandTree.includes(node.key) ? expandTree.filter(ele => ele !== node.key) : [...expandTree, ...selectedKeys]
setExpandTree(_expandTree)
}
}
const [selectedEmail, setSelectedEmail] = useState({});
const onClickEmailItem = (emailItem) => {
const mai_sn = emailItem.MAI_SN;
setActiveEmailId(mai_sn);
setMailboxActiveCOLI(emailItem.MAI_COLI_SN || 0)
const emailMsg = {
conversationid: '',
order_opi: currentMailboxOPI,
coli_sn: 'oid',
id: emailItem.MAI_SN,
MAI_SN: emailItem.MAI_SN,
msgOrigin: {
from: '',
to: '',
...(emailItem?.msgOrigin || {}),
id: emailItem.MAI_SN,
email: { mai_sn: emailItem.MAI_SN, subject: emailItem.MAI_Subject, id: emailItem.MAI_SN },
subject: emailItem.MAI_Subject,
},
}
// console.log('emailItem', emailItem);
setSelectedEmail(emailMsg)
};
// 1新订单2未读消息3需一催4需二催5需三催6未处理邮件入境提醒coli_ordertype=7余款提醒coli_ordertype=8
useEffect(() => {
const first = currentMailboxDEI || accountDEI[0].value
const opi = accountListDEIMapped[first].OPI_SN
setExpandTree([...[`${opi}-today`, `${opi}-todo`, `search-orders` ]])
return () => {}
}, [currentMailboxDEI ])
useEffect(() => {
if (mailboxActiveNode?.expand === true) {
setExpandTree([mailboxActiveNode.key])
}
return () => {}
}, [mailboxActiveNode])
useEffect(() => {
const targetRect = mailboxTreeRef.current?.getBoundingClientRect()
setTreeHeight(Math.floor(targetRect.height))
return () => {}
}, [])
const isVisible = useVisibilityState();
useEffect(() => {
// console.log('effect isVisible', isVisible);
if (isVisible && currentMailboxOPI) {
getOPIEmailDir(currentMailboxOPI, null, true)
}
return () => {}
}, [isVisible]);
return (
<>
<Layout>
<Layout.Sider width='300' theme='light' style={{ height: 'calc(100vh - 166px)' }} className=' relative'>
<Flex justify='start' align='start' vertical className='h-full'>
<Segmented className='w-full' block shape='round' options={accountDEI} value={currentMailboxDEI} onChange={handleSwitchAccount} />
<div ref={mailboxTreeRef} className='overflow-y-auto flex-auto w-full [&_.ant-tree-switcher]:me-0 [&_.ant-tree-node-content-wrapper]:px-0 [&_.ant-tree-node-content-wrapper]:text-ellipsis [&_.ant-tree-node-content-wrapper]:overflow-hidden [&_.ant-tree-node-content-wrapper]:whitespace-nowrap'>
<Tree
className='[&_.ant-typography-ellipsis]:max-w-44 [&_.ant-typography-ellipsis]:min-w-36'
key='sticky-today'
blockNode
showIcon
showLine
height={treeHeight}
autoExpandParent={true}
expandAction={'doubleClick'}
onSelect={handleTreeSelectGetMails}
selectedKeys={[mailboxActiveNode.key]}
onExpand={(expandedKeys) => setExpandTree(expandedKeys)}
expandedKeys={expandTree}
defaultExpandedKeys={expandTree}
treeData={mailboxNestedDirsActive}
icon={(node) => <MailboxDirIcon type={node?.iconIndex} />}
titleRender={(node) => (
<Typography.Text ellipsis={{ tooltip: node.title }} className={`${node?._raw?.IsSuccess === 1 ? 'text-primary' : ''}`}>
{node.title}
<Badge size={'small'} count={node.count} offset={[3, 0]} style={{backgroundColor: "#1ba784", color1: '#1ba784'}} overflowCount={999} />
</Typography.Text>
)}
/>
</div>
</Flex>
</Layout.Sider>
<Layout.Content style={{ maxHeight: 'calc(100vh - 166px)', height: 'calc(100vh - 166px)', minWidth: '360px' }}>
<Splitter>
<Splitter.Panel defaultSize='40%' min={380} max='70%'>
<Mailbox breadcrumb={computedBreadcrumb} mailboxDir={mailboxActiveNode} onMailItemClick={(item) => onClickEmailItem(item)} currentActiveMailItem={activeEmailId} />
</Splitter.Panel>
<Splitter.Panel>
<EmailDetailInline mailID={activeEmailId || 0} emailMsg={selectedEmail} variant={'outline'} size={'small'} onUpdated={(prop) => {}} autoMark={true} />
</Splitter.Panel>
</Splitter>
</Layout.Content>
<Tooltip title={(collapsed ? '展开' : '收起') + '订单信息'} placement='left'>
<Button
icon={collapsed ? <LeftOutlined /> : <UnorderedListOutlined />}
onClick={() => setCollapsed(!collapsed)}
className={`absolute z-10 rounded-none ${collapsed ? 'right-1 top-20 rounded-l-xl' : 'right-8 top-20 rounded-l'}`}
size={collapsed ? 'small' : 'middle'}
/>
</Tooltip>
<Layout.Sider
width='280'
theme='light'
className='overflow-y-auto'
style={{
height: 'calc(100vh - 166px)',
}}
collapsible
collapsed={collapsed}
onCollapse={(value) => setCollapsed(value)}
collapsedWidth={0}
trigger={null}
reverseArrow={true}>
<OrderProfile coliSN={mailboxActiveCOLI} />
</Layout.Sider>
</Layout>
</>
)
}
export default Follow