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

263 lines
11 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 useFormStore from '@/stores/FormStore'
import { useOrderStore } from '@/stores/OrderStore'
import { isEmpty, groupBy, buildTree, readIndexDB, writeIndexDB, pick } from '@/utils/commons'
import { StarTwoTone, CalendarTwoTone, FolderOutlined, DeleteOutlined, ClockCircleOutlined, FormOutlined, DatabaseOutlined, UnorderedListOutlined, LeftOutlined } from '@ant-design/icons'
import { Flex, Drawer, Radio, Divider, Segmented, Tree, Typography, Checkbox, Layout, Row, Col, Empty, Splitter, Button } from 'antd'
import { useEffect, useMemo, useState } from 'react'
import { InboxIcon, MailUnreadIcon, SendPlaneFillIcon } from '@/components/Icons'
import { useShallow } from 'zustand/react/shallow'
import EmailDetailInline from '../Conversations/Online/Components/EmailDetailInline'
import { getEmailDirAction, queryEmailListAction } from '@/actions/EmailActions'
import OrderProfile from '@/components/OrderProfile'
import Mailbox from './components/Mailbox'
import useConversationStore from '@/stores/ConversationStore';
import dayjs from 'dayjs'
import { DATE_FORMAT, DATETIME_FORMAT } from '@/config'
import { MailboxDirIcon } from './components/MailboxDirIcon'
const todoTypes = {
// 1新订单2未读消息3需一催4需二催5需三催6未处理邮件入境提醒coli_ordertype=7余款提醒coli_ordertype=8
1: '新订单',
2: '未读',
3: '一催',
4: '二催',
5: '三催',
6: '未处理',
7: '入境提醒',
8: '余款提醒',
}
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 orderList = useOrderStore((state) => state.orderList)
const fetchOrderList = useOrderStore((state) => state.fetchOrderList)
const [collapsed, setCollapsed] = useState(false)
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 defaultStickyTree = useMemo(() => {
return accountList.reduce(
(a, ele) => ({
...a,
[ele.OPI_DEI_SN]: [
{
title: '今日任务',
key: ele.OPI_DEI_SN + '-today',
getMails: false, iconIndex: 'star',
icon: <StarTwoTone />,
children: [], COLI_SN: 0,
},
{
title: '待办任务',
key: ele.OPI_DEI_SN + '-todo',
getMails: false, iconIndex: 'calendar',
icon: <CalendarTwoTone />,
children: [], COLI_SN: 0,
},
],
}),
{},
)
}, [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 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 [activeEmailId, setActiveEmailId] = useState(0)
const [deiStickyTree, setDeiStickyTree] = useState({})
const [stickyTree, setStickyTree] = useState([])
const [expandTree, setExpandTree] = useState([])
const handleSwitchAccount = (value) => {
setActiveEmailId(0);
setCurrentMailboxDEI(value)
setStickyTree(deiStickyTree[value] || [])
setExpandTree([`${value}-today`, `${value}-todo`])
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);
}
}
useEffect(() => {
fetchOrderList({ type: 'today' }, loginUser)
return () => {}
}, [])
// 1新订单2未读消息3需一催4需二催5需三催6未处理邮件入境提醒coli_ordertype=7余款提醒coli_ordertype=8
useEffect(() => {
console.log('orderList render', currentMailboxDEI, currentMailboxOPI)
const byDEI = groupBy(orderList, 'OPI_DEI_SN')
// console.log(byDEI, 'byDEI')
const byState = Object.keys(byDEI).reduce((acc, key) => {
// const stickyIndex0 = byDEI[key].filter(ele => [1, 2, 6].includes(ele.COLI_StateCode))
// const stickyIndex1 = byDEI[key].filter(ele => ![1, 2, 6].includes(ele.COLI_StateCode))
const sticky = groupBy(byDEI[key], (ele) => ([1, 2, 6].includes(ele.coli_ordertype) ? 0 : 1))
// const sticky = groupBy(byDEI[key], ele => [1, 2, 6].includes(ele.COLI_StateCode) ? 'today' : 'todo');
// console.log(sticky, ';;;;');
// const deiName = deptMap.get(`${key}`);
const treeNode = [
{
title: '今日任务',
key: key + '-today',
getMails: false,iconIndex: 'star',
icon: <StarTwoTone />, _raw: {COLI_SN: 0, IsTrue: 0,},
children: (sticky[0] || []).map((o) => ({
key: `today-${o.COLI_SN}`,
title: `(${todoTypes[o.coli_ordertype] || o.COLI_State}) ${o.COLI_ID}`,
iconIndex: 13,
parent: key + '-today',
parentTitle: '今日任务',
parentIconIndex: 'star',
_raw: { ...o, VKey: o.COLI_SN, VName: o.COLI_ID, VParent:-1, IsTrue: 0, ApplyDate: '', OrderSourceType: 227001, parent: -1 },
})),
},
{
title: '待办任务',
key: key + '-todo',
getMails: false,iconIndex: 'calendar',
icon: <CalendarTwoTone />,_raw: {COLI_SN: 0, IsTrue: 0,},
children: (sticky[1] || []).map((o) => ({
key: `todo-${o.COLI_SN}`,
title: `(${todoTypes[o.coli_ordertype] || o.COLI_State}) ${o.COLI_ID}`,
iconIndex: 13,
parent: key + '-todo',
parentTitle: '待办任务',
parentIconIndex: 'calendar',
_raw: { ...o, VKey: o.COLI_SN, VName: o.COLI_ID, VParent:-1, IsTrue: 0, ApplyDate: '', OrderSourceType: 227001, parent: -1 },
})),
},
]
// { key, title: deiName, children: sticky[0] };
return { ...acc, [key]: treeNode }
}, defaultStickyTree)
// console.log('tree 0', byState);
setDeiStickyTree(byState)
const first = currentMailboxDEI || accountDEI[0].value
setExpandTree([`${first}-today`, `${first}-todo`, mailboxActiveNode.key])
setStickyTree(byState[first] || [])
return () => {}
}, [orderList])
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 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
key='sticky-today'
blockNode
showIcon
showLine autoExpandParent={true}
expandAction={'doubleClick'}
onSelect={handleTreeSelectGetMails}
selectedKeys={[mailboxActiveNode.key]}
onExpand={(expandedKeys) => setExpandTree(expandedKeys)}
expandedKeys={expandTree}
defaultExpandedKeys={expandTree}
treeData={[...(stickyTree || []), ...mailboxNestedDirsActive]}
// treeData={mergedTree}
icon={(node) => <MailboxDirIcon type={node?.iconIndex} />}
titleRender={(node) => <Typography.Text ellipsis={{ tooltip: node.title }}>{node.title}</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={580} max='70%'>
<Mailbox breadcrumb={computedBreadcrumb} mailboxDir={mailboxActiveNode} onMailItemClick={(id) => setActiveEmailId(id)} />
</Splitter.Panel>
<Splitter.Panel>
<EmailDetailInline mailID={activeEmailId || 0} emailMsg={{}} variant={'outline'} size={'small'} />
</Splitter.Panel>
</Splitter>
</Layout.Content>
<Button icon={collapsed ? <LeftOutlined /> : <UnorderedListOutlined />} onClick={() => setCollapsed(!collapsed)} className={`absolute z-10 rounded-none rounded-l ${collapsed ? 'right-1 top-36' : 'right-8 top-20'}`} />
<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={mailboxActiveNode.COLI_SN} />
</Layout.Sider>
</Layout>
</>
)
}
export default Follow