feat: 增加【查找邮件】界面

main
LiaoYijun 5 days ago
parent 2b344eec43
commit d5a522e88f

@ -375,6 +375,16 @@ export const queryEmailListAction = async ({ opi_sn = '', pagesize = 10, last_id
return ret; return ret;
} }
export const searchEmailListAction = async (opi_sn = '', mailboxtype = 'ALL', sender = '', receiver = '', subject = '') => {
const formData = new FormData()
formData.append('opi_sn', opi_sn)
formData.append('mailboxtype', mailboxtype)
const { errcode, result } = await postForm(`${API_HOST_V3}/mail_search`, formData)
const ret = errcode === 0 ? result : []
return ret;
}
const removeFromCurrentList = async (params) => { const removeFromCurrentList = async (params) => {
const readRow0 = await readIndexDB(params.mai_sn_list[0], 'listrow', 'mailbox') const readRow0 = await readIndexDB(params.mai_sn_list[0], 'listrow', 'mailbox')
const listKey = readRow0?.data?.listKey || '' const listKey = readRow0?.data?.listKey || ''

@ -1,7 +1,7 @@
import { useState, useEffect, useCallback } from 'react' import { useState, useEffect, useCallback } from 'react'
import { isEmpty, objectMapper, olog, } from '@/utils/commons' import { isEmpty, objectMapper, olog, } from '@/utils/commons'
import { readIndexDB } from '@/utils/indexedDB' import { readIndexDB } from '@/utils/indexedDB'
import { getEmailDetailAction, postResendEmailAction, getSalesSignatureAction, getEmailOrderAction, queryEmailListAction, getReminderEmailTemplateAction, saveEmailDraftOrSendAction, updateEmailAction, getEmailChangesChannel, EMAIL_CHANNEL_NAME } from '@/actions/EmailActions' import { getEmailDetailAction, postResendEmailAction, getSalesSignatureAction, getEmailOrderAction, queryEmailListAction, searchEmailListAction, getReminderEmailTemplateAction, saveEmailDraftOrSendAction, updateEmailAction, getEmailChangesChannel, EMAIL_CHANNEL_NAME } from '@/actions/EmailActions'
import { App } from 'antd' import { App } from 'antd'
import useConversationStore from '@/stores/ConversationStore'; import useConversationStore from '@/stores/ConversationStore';
import { msgStatusRenderMapped } from '@/channel/bubbleMsgUtils'; import { msgStatusRenderMapped } from '@/channel/bubbleMsgUtils';
@ -176,6 +176,7 @@ export const useEmailList = (mailboxDirNode) => {
setRefreshTrigger((prev) => prev + 1) setRefreshTrigger((prev) => prev + 1)
}, []) }, [])
const [currentMailboxOPI] = useConversationStore((state) => [state.currentMailboxOPI])
const { OPI_SN: opi_sn, COLI_SN, VKey, VParent, ApplyDate, OrderSourceType, IsTrue } = mailboxDirNode const { OPI_SN: opi_sn, COLI_SN, VKey, VParent, ApplyDate, OrderSourceType, IsTrue } = mailboxDirNode
const markAsRead = useCallback( const markAsRead = useCallback(
@ -233,6 +234,17 @@ export const useEmailList = (mailboxDirNode) => {
} }
}, [VKey]) }, [VKey])
const searchMailList = async () => {
const searchResult = await searchEmailListAction(currentMailboxOPI, 'ALL')
// 配合List的结构
const mailList = searchResult.map((ele) => ({
...ele,
key: ele.MAI_SN,
}))
setMailList(mailList)
console.info('searchMailList', searchResult)
}
const getMailList = useCallback(async () => { const getMailList = useCallback(async () => {
// console.log('getMailList', mailboxDirNode) // console.log('getMailList', mailboxDirNode)
if (!opi_sn || !VKey || (!IsTrue && !COLI_SN)) { if (!opi_sn || !VKey || (!IsTrue && !COLI_SN)) {
@ -297,7 +309,7 @@ export const useEmailList = (mailboxDirNode) => {
} }
}, [getMailList]) }, [getMailList])
return { loading, isFreshData, error, mailList, refresh, markAsRead, markAsProcessed, markAsDeleted } return { loading, isFreshData, error, mailList, refresh, markAsRead, markAsProcessed, markAsDeleted, searchMailList }
} }
const orderMailTypes = new Map([ const orderMailTypes = new Map([

@ -1,48 +1,21 @@
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { ReloadOutlined, ReadOutlined, RightOutlined, LeftOutlined, SearchOutlined, MailOutlined, DeleteOutlined } from '@ant-design/icons' import { ReloadOutlined, ReadOutlined, RightOutlined, LeftOutlined, SearchOutlined, MailOutlined, DeleteOutlined } from '@ant-design/icons'
import { Flex, Button, Tooltip, List, Form, Row, Col, Input, Checkbox, DatePicker, Switch, Breadcrumb, Skeleton, Popconfirm } from 'antd' import { Flex, Button, Tooltip, List, Form, Row, Col, Input, Checkbox, DatePicker, Switch, Breadcrumb, Skeleton, Popconfirm } from 'antd'
import dayjs from 'dayjs'
import { useEmailList } from '@/hooks/useEmail' import { useEmailList } from '@/hooks/useEmail'
import { isEmpty } from '@/utils/commons' import { isEmpty } from '@/utils/commons'
import { MailboxDirIcon } from './MailboxDirIcon' import { MailboxDirIcon } from './MailboxDirIcon'
import { AttachmentIcon, MailCheckIcon, MailOpenIcon } from '@/components/Icons' import { AttachmentIcon, MailCheckIcon, MailOpenIcon } from '@/components/Icons'
import NewEmailButton from './NewEmailButton' import NewEmailButton from './NewEmailButton'
import MailOrderSearchModal from './MailOrderSearchModal' import MailOrderSearchModal from './MailOrderSearchModal'
import MailListSearchModal from './MailListSearchModal'
const { RangePicker } = DatePicker
const PAGE_SIZE = 50 // const PAGE_SIZE = 50 //
const MailBox = ({ mailboxDir, onMailItemClick, ...props }) => { const MailBox = ({ mailboxDir, onMailItemClick, ...props }) => {
const DATE_RANGE_PRESETS = [
{
label: '本周',
value: [dayjs().startOf('w'), dayjs().endOf('w')],
},
{
label: '上周',
value: [dayjs().startOf('w').subtract(7, 'days'), dayjs().endOf('w').subtract(7, 'days')],
},
{
label: '本月',
value: [dayjs().startOf('M'), dayjs().endOf('M')],
},
{
label: '上月',
value: [dayjs().subtract(1, 'M').startOf('M'), dayjs().subtract(1, 'M').endOf('M')],
},
{
label: '前三月',
value: [dayjs().subtract(2, 'M').startOf('M'), dayjs().endOf('M')],
},
{
label: '本年',
value: [dayjs().startOf('y'), dayjs().endOf('y')],
},
]
const [form] = Form.useForm()
const [selectedItems, setSelectedItems] = useState([]) const [selectedItems, setSelectedItems] = useState([])
const { mailList, loading, error, refresh, markAsRead, markAsProcessed, markAsDeleted } = useEmailList(mailboxDir) const { mailList, loading, error, refresh, markAsRead, markAsProcessed, markAsDeleted, searchMailList } = useEmailList(mailboxDir)
const [pagination, setPagination] = useState({ const [pagination, setPagination] = useState({
current: 1, current: 1,
@ -189,33 +162,17 @@ const MailBox = ({ mailboxDir, onMailItemClick, ...props }) => {
删除 删除
</Button> </Button>
<MailOrderSearchModal /> <MailOrderSearchModal />
<MailListSearchModal mailboxDir={mailboxDir} />
{/* <Button
size='small'
icon={<DeleteOutlined />}
onClick={() => {
searchMailList()
}}>
查找邮件
</Button> */}
</Flex> </Flex>
</div> </div>
<div className='bg-white h-auto p-1 flex gap-1 items-center hidden'>
<Form
form={form}
initialValues={{}}
// onFinish={handleSubmit}
>
<Row justify='start' gutter={16}>
<Col span={10}>
<Form.Item label='订单号' name='orderNumber'>
<Input placeholder='订单号' allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label='日期' name='confirmDateRange'>
<RangePicker allowClear={true} inputReadOnly={true} presets={DATE_RANGE_PRESETS} />
</Form.Item>
</Col>
<Col span={1} offset={1}>
<Button type='primary' htmlType='submit'>
搜索
</Button>
</Col>
</Row>
</Form>
</div>
<Flex align='center' justify='space-between' wrap className='px-1 border-0 border-b border-solid border-neutral-200'> <Flex align='center' justify='space-between' wrap className='px-1 border-0 border-b border-solid border-neutral-200'>
<Breadcrumb <Breadcrumb
items={props.breadcrumb.map((bc) => { items={props.breadcrumb.map((bc) => {

@ -0,0 +1,82 @@
import { createContext, useEffect, useState } from 'react'
import { ReloadOutlined, ReadOutlined, RightOutlined, LeftOutlined, SearchOutlined, MailOutlined } from '@ant-design/icons'
import { Button, Modal, Form, Input, Checkbox, Select, Radio, Segmented, Divider, Typography, Flex } from 'antd'
import dayjs from 'dayjs'
import { getEmailDirAction, queryHTOrderListAction, searchEmailListAction } from '@/actions/EmailActions'
import { isEmpty, objectMapper, pick } from '@/utils/commons'
import useConversationStore from '@/stores/ConversationStore'
import { useEmailList } from '@/hooks/useEmail'
const MailListSearchModal = ({ ...props }) => {
const [currentMailboxOPI] = useConversationStore((state) => [state.currentMailboxOPI])
const { searchMailList } = useEmailList(props.mailboxDir)
const [openForm, setOpenForm] = useState(false)
const [formSearch] = Form.useForm()
const [loading, setLoading] = useState(false)
const onSubmitSearchMailList = async (values) => {
setLoading(true)
searchMailList()
setLoading(false)
setOpenForm(false)
}
return (
<>
<Button key={'bound'} onClick={() => setOpenForm(true)} size='small' icon={<SearchOutlined className='' />}>
查找订单
</Button>
<Modal
width={window.innerWidth < 700 ? '95%' : 960}
open={openForm}
cancelText='关闭'
okText='查找'
confirmLoading={loading}
okButtonProps={{ autoFocus: true, htmlType: 'submit', type: 'default' }}
onCancel={() => setOpenForm(false)}
footer={null}
destroyOnHidden
modalRender={(dom) => (
<Form
layout='vertical'
form={formSearch}
name='searchmaillist_form_in_modal'
initialValues={{ mailboxtype: '1' }}
clearOnDestroy
onFinish={(values) => onSubmitSearchMailList(values)}
className='[&_.ant-form-item]:m-2'>
{dom}
</Form>
)}>
<Form.Item name='mailboxtype' label='文件夹'>
<Radio.Group
options={[
{ key: '-1', value: 'ALL', label: 'All' },
{ key: '1', value: '1', label: '收件箱' },
{ key: '2', value: '2', label: '未读邮件' },
{ key: '3', value: '3', label: '已发邮件' },
{ key: '4', value: '4', label: '待发邮件' },
{ key: '5', value: '5', label: '草稿' },
{ key: '6', value: '6', label: '已发邮件' },
{ key: '7', value: '7', label: '已处理邮件' },
]}
optionType='button'
/>
</Form.Item>
<Form.Item name='sender' label='发件人'>
<Input />
</Form.Item>
<Form.Item name='receiver' label='收件人'>
<Input />
</Form.Item>
<Form.Item name='subject' label='主题'>
<Input />
</Form.Item>
<Button type='primary' htmlType='submit' loading={loading}>
查找
</Button>
</Modal>
</>
)
}
export default MailListSearchModal

@ -60,7 +60,7 @@ const MailOrderSearchModal = ({ ...props }) => {
return ( return (
<> <>
<Button key={'bound'} onClick={() => setOpen(true)} size='small' icon={<SearchOutlined className='' />}> <Button key={'bound'} onClick={() => setOpen(true)} size='small' icon={<SearchOutlined className='' />}>
查找 查找订单
</Button> </Button>
<Modal <Modal
width={window.innerWidth < 700 ? '95%' : 960} width={window.innerWidth < 700 ? '95%' : 960}

Loading…
Cancel
Save