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/components/MailBox.jsx

218 lines
8.0 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 { useEffect, useState } from 'react'
import { ReloadOutlined, ReadOutlined, RightOutlined, LeftOutlined, SearchOutlined, MailOutlined, DeleteOutlined, CloseOutlined, CloseCircleTwoTone, CloseCircleOutlined } from '@ant-design/icons'
import { Flex, Button, Tooltip, List, Form, Row, Col, Input, Checkbox, DatePicker, Switch, Breadcrumb, Skeleton, Popconfirm } from 'antd'
import { useEmailList } from '@/hooks/useEmail'
import { isEmpty } from '@/utils/commons'
import { MailboxDirIcon } from './MailboxDirIcon'
import { AttachmentIcon, MailCheckIcon, MailOpenIcon } from '@/components/Icons'
import NewEmailButton from './NewEmailButton'
import MailOrderSearchModal from './MailOrderSearchModal'
import MailListSearchModal from './MailListSearchModal'
const PAGE_SIZE = 50 // 每页显示条数
const MailBox = ({ mailboxDir, onMailItemClick, ...props }) => {
const [selectedItems, setSelectedItems] = useState([])
const { mailList, loading, error, tempBreadcrumb, refresh, markAsUnread, markAsProcessed, markAsDeleted, } = useEmailList(mailboxDir)
const [pagination, setPagination] = useState({
current: 1,
pageSize: PAGE_SIZE,
total: 0,
pagedList: [],
})
useEffect(() => {
if (mailList) {
const total = mailList.length
const pageCount = Math.ceil(total / PAGE_SIZE)
setPagination((prev) => ({
...prev,
total,
pageCount,
current: 1, // 重置到第一页
pagedList: getPagedData(mailList, 1),
}))
}
}, [mailList])
const getPagedData = (data, currentPage) => {
const startIndex = (currentPage - 1) * PAGE_SIZE
const endIndex = Math.min(startIndex + PAGE_SIZE, data.length)
return data.slice(startIndex, endIndex)
}
const prePage = () => {
if (pagination.current > 1) {
const newCurrent = pagination.current - 1
setPagination((prev) => ({
...prev,
current: newCurrent,
pagedList: getPagedData(mailList, newCurrent),
}))
}
}
const nextPage = () => {
if (pagination.current < Math.ceil(pagination.total / PAGE_SIZE)) {
const newCurrent = pagination.current + 1
setPagination((prev) => ({
...prev,
current: newCurrent,
pagedList: getPagedData(mailList, newCurrent),
}))
}
}
const mailItemRender = (item) => {
const isOrderNode = mailboxDir.COLI_SN > 0
const orderNumber = isEmpty(item.MAI_COLI_ID) || isOrderNode ? '' : item.MAI_COLI_ID + ' - '
const folderName = (item.showFolder) ? `[${item.FDir}] ` : ''
const orderMailType = item.MAT_Name ? <span className='text-neutral-600 text-xs'>{item.MAT_Name}</span> : ''
const countryName = isEmpty(item.CountryCN) ? '' : '[' + item.CountryCN + '] '
const mailStateClass = item.MOI_ReadState === 0 ? 'font-bold' : ''
const hasAtta = item.MAI_Attachment !== 0 ? <AttachmentIcon className='text-blue-500' /> : null
return (
<li
className={`flex border border-solid border-t-0 border-x-0 border-gray-200 hover:bg-neutral-50 active:bg-gray-200 p-2 ${props.currentActiveMailItem === item.MAI_SN ? 'bg-neutral-100' : ''}`}>
<div className=''>
<Checkbox
checked={selectedItems.some((i) => i.MAI_SN === item.MAI_SN)}
onClick={(e) => {
const isChecked = e.target.checked
const updatedSelection = isChecked ? [...selectedItems, item] : selectedItems.filter((item) => item.MAI_SN !== item.MAI_SN)
setSelectedItems(updatedSelection)
}}></Checkbox>
</div>
<div
className='flex-1 pl-2'
onClick={() => {
onMailItemClick(item)
}}>
<Flex gap='small' vertical={true} justify='space-between' className='cursor-pointer'>
<div>
{folderName}{orderNumber}
<span className={mailStateClass}>{item.MAI_Subject || '[无主题]'}</span>
{hasAtta}
</div>
<Flex gap='small' align='center' justify='flex-end' wrap className='text-neutral-500 text-wrap break-words break-all '>
<span className='mr-auto'>{countryName + item.SenderReceiver}</span>
{orderMailType}
<span className=''>{item.SRDate}</span>
</Flex>
</Flex>
</div>
</li>
)
}
return (
<div className='h-full flex flex-col gap-1 bg-white'>
<div className='bg-white h-auto px-1 flex gap-1 items-center'>
<Flex wrap gap='middle' justify={'center'} className='min-w-30 px-1'>
<Tooltip title='全选'>
<Checkbox
indeterminate={selectedItems.length > 0 && selectedItems.length < pagination.pagedList.length}
checked={pagination.pagedList.length === 0 ? false : pagination.pagedList.every((item) => selectedItems.some((selected) => selected.MAI_SN === item.MAI_SN))}
onChange={(e) => {
const isChecked = e.target.checked
if (isChecked) {
setSelectedItems((prev) => [...prev, ...pagination.pagedList])
} else {
setSelectedItems([])
}
}}></Checkbox>
</Tooltip>
<Tooltip title='刷新'>
<Button shape='circle' type='text' size='small' icon={<ReloadOutlined />} onClick={refresh} />
</Tooltip>
</Flex>
<Flex wrap gap={8} >
<NewEmailButton />
<Button
size='small'
icon={<MailOutlined />}
onClick={() => {
markAsUnread(selectedItems.map((item) => item.MAI_SN)).then(() => setSelectedItems([]))
}}>
未读
</Button>
<Button
size='small'
icon={<MailCheckIcon />}
onClick={() => {
markAsProcessed(selectedItems.map((item) => item.MAI_SN)).then(() => setSelectedItems([]))
}}>
已处理
</Button>
<Button
size='small' // danger
icon={<DeleteOutlined />}
onClick={() => {
markAsDeleted(selectedItems.map((item) => item.MAI_SN)).then(() => setSelectedItems([]))
}}>
删除
</Button>
<MailOrderSearchModal />
<MailListSearchModal />
</Flex>
</div>
<Flex align='center' justify='space-between' wrap className='px-1 border-0 border-b border-solid border-neutral-200'>
<Breadcrumb
items={(tempBreadcrumb || props.breadcrumb).map((bc) => {
return {
title: (
<>
<MailboxDirIcon type={bc?.iconIndex} />
<span>{bc.title}</span>
</>
),
}
})}
/>
{tempBreadcrumb && (<Button type="text" icon={<CloseCircleOutlined />} onClick={() => refresh()} />)}
<Flex align='center' justify='space-between' className='ml-auto'>
<span>已选: {selectedItems.length} </span>
<span>
{(pagination.current - 1) * PAGE_SIZE + 1}-{Math.min(pagination.current * PAGE_SIZE, pagination.total)} of {pagination.total}
</span>
<Button
icon={<LeftOutlined />}
type='text'
onClick={() => {
prePage()
}}
iconPosition={'end'}></Button>
<Button
icon={<RightOutlined />}
type='text'
onClick={() => {
nextPage()
}}
iconPosition={'end'}></Button>
</Flex>
</Flex>
<div className='bg-white overflow-auto px-2' style={{ height1: 'calc(100vh - 198px)' }}>
<Skeleton active loading={loading}>
<List
loading={loading}
className='flex flex-col h-full [&_.ant-list-items]:overflow-auto'
header={null}
itemLayout='vertical'
pagination={false}
dataSource={pagination.pagedList}
renderItem={mailItemRender}
/>
</Skeleton>
</div>
</div>
)
}
export default MailBox