feat: 查找邮件: 更新

main
Lei OT 5 days ago
parent 01997b7d23
commit cbf63c5e86

@ -348,7 +348,6 @@ export const getRootMailboxDirAction = async ({ opi_sn = 0, userIdStr = '' } = {
* 获取邮件列表 * 获取邮件列表
* @usage 邮件目录下的邮件列表 * @usage 邮件目录下的邮件列表
* @usage 订单的邮件列表 * @usage 订单的邮件列表
* @usage 高级搜索
*/ */
export const queryEmailListAction = async ({ opi_sn = '', pagesize = 10, last_id = '', node = {}, } = {}) => { export const queryEmailListAction = async ({ opi_sn = '', pagesize = 10, last_id = '', node = {}, } = {}) => {
const _params = { const _params = {
@ -375,13 +374,17 @@ 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 = '') => { export const searchEmailListAction = async ({opi_sn = '', mailboxtype = 'ALL', sender = '', receiver = '', subject = '', content=''}={}) => {
const formData = new FormData() const formData = new FormData()
formData.append('opi_sn', opi_sn) formData.append('opi_sn', opi_sn)
formData.append('mailboxtype', mailboxtype) formData.append('mailboxtype', mailboxtype)
formData.append('sender', sender)
formData.append('receiver', receiver)
formData.append('subject', subject)
// formData.append('content', content)
const { errcode, result } = await postForm(`${API_HOST_V3}/mail_search`, formData) const { errcode, result } = await postForm(`${API_HOST_V3}/mail_search`, formData)
const ret = errcode === 0 ? result : [] const ret = errcode === 0 ? result : []
notifyMailboxUpdate({ type: 'maillist-search-result', query: [sender, receiver, subject].filter(s => s).join(' '), data: ret.map(ele => ({...ele, key: ele.MAI_SN})) })
return ret; return ret;
} }
@ -486,7 +489,3 @@ export const queryOPIOrderAction = async (params) => {
return errcode !== 0 ? [] : result return errcode !== 0 ? [] : result
}; };
export const queryInMailboxAction = async (params) => {
const { errcode, result } = await fetchJSON(`${API_HOST_V3}/mail_search`, params)
return errcode !== 0 ? [] : result
}

@ -171,6 +171,7 @@ export const useEmailList = (mailboxDirNode) => {
const [error, setError] = useState(null) const [error, setError] = useState(null)
const [isFreshData, setIsFreshData] = useState(false) const [isFreshData, setIsFreshData] = useState(false)
const [refreshTrigger, setRefreshTrigger] = useState(0) const [refreshTrigger, setRefreshTrigger] = useState(0)
const [tempBreadcrumb, setTempBreadcrumb] = useState(null);
const refresh = useCallback(() => { const refresh = useCallback(() => {
setRefreshTrigger((prev) => prev + 1) setRefreshTrigger((prev) => prev + 1)
@ -234,15 +235,15 @@ export const useEmailList = (mailboxDirNode) => {
} }
}, [VKey]) }, [VKey])
const searchMailList = async () => { const searchMailList = async (params) => {
const searchResult = await searchEmailListAction(currentMailboxOPI, 'ALL') // const searchResult = await searchEmailListAction({ ...params, opi_sn: currentMailboxOPI })
// 配合List的结构 // // 配合List的结构
const mailList = searchResult.map((ele) => ({ // const mailList = searchResult.map((ele) => ({
...ele, // ...ele,
key: ele.MAI_SN, // key: ele.MAI_SN,
})) // }))
setMailList(mailList) // setMailList(mailList)
console.info('searchMailList', searchResult) // console.info('searchMailList', searchResult)
} }
const getMailList = useCallback(async () => { const getMailList = useCallback(async () => {
@ -254,7 +255,7 @@ export const useEmailList = (mailboxDirNode) => {
setIsFreshData(false) setIsFreshData(false)
return return
} }
setTempBreadcrumb(null)
setLoading(true) setLoading(true)
setError(null) setError(null)
setIsFreshData(false) setIsFreshData(false)
@ -283,10 +284,19 @@ export const useEmailList = (mailboxDirNode) => {
getMailList() getMailList()
// --- Setup Internal Event Listener --- // --- Setup Internal Event Listener ---
const handleInternalUpdate = (event) => { const handleInternalUpdate = (event) => {
// console.log(`[useEmailList] Received internal event. `, event.detail) // console.log(`🔔[useEmailList] Received internal event. `, event.detail)
if (event.detail && event.detail.type === 'listrow') { if (isEmpty(event.detail)) {
return false;
}
const { type, } = event.detail
if (type === 'listrow') {
loadMailListFromCache() loadMailListFromCache()
} }
if (type === 'maillist-search-result') {
const { data, query } = event.detail
setMailList(data)
setTempBreadcrumb([{title: '查找邮件:'+query, iconIndex: 'search'}]);
}
} }
internalEventEmitter.on(EMAIL_CHANNEL_NAME, handleInternalUpdate) internalEventEmitter.on(EMAIL_CHANNEL_NAME, handleInternalUpdate)
@ -294,11 +304,20 @@ export const useEmailList = (mailboxDirNode) => {
const channel = getEmailChangesChannel() const channel = getEmailChangesChannel()
const handleMessage = (event) => { const handleMessage = (event) => {
// console.log(`[useEmailList] Received channel event. `, event.data) // console.log(`[useEmailList] Received channel event. `, event.data)
if (isEmpty(event.data)) {
return false;
}
const { type, } = event.detail
const cacheKey = isEmpty(COLI_SN) ? `dir-${VKey}` : `order-${VKey}` const cacheKey = isEmpty(COLI_SN) ? `dir-${VKey}` : `order-${VKey}`
if (event.data.type === 'listrow' && cacheKey === event.data.listKey) { if (type === 'listrow' && cacheKey === event.data.listKey) {
// cacheKey 不相同时, 不需要更新; 邮箱目录不相同 // cacheKey 不相同时, 不需要更新; 邮箱目录不相同
loadMailListFromCache(event.data) loadMailListFromCache(event.data)
} }
if (type === 'maillist-search-result') {
// 搜索的结果不需要更新所有页面
// const { data } = event.detail
// setMailList(data)
}
} }
channel.addEventListener('message', handleMessage) channel.addEventListener('message', handleMessage)
@ -309,7 +328,7 @@ export const useEmailList = (mailboxDirNode) => {
} }
}, [getMailList]) }, [getMailList])
return { loading, isFreshData, error, mailList, refresh, markAsRead, markAsProcessed, markAsDeleted, searchMailList } return { loading, isFreshData, error, mailList, tempBreadcrumb, refresh, markAsRead, markAsProcessed, markAsDeleted, searchMailList }
} }
const orderMailTypes = new Map([ const orderMailTypes = new Map([
@ -428,12 +447,12 @@ export const useEmailTemplate = (templateKey, params) => {
} }
export const mailboxSystemDirs = [ export const mailboxSystemDirs = [
{ key: 1, value: 1, label: '收件箱' }, { key: 1, value: 1, label: '收件箱' },
{ key: 2, value: 2, label: '未读邮件' }, { key: 2, value: 2, label: '未读邮件' },
{ key: 3, value: 3, label: '已发邮件' }, { key: 3, value: 3, label: '已发邮件' },
{ key: 4, value: 4, label: '待发邮件' }, { key: 4, value: 4, label: '待发邮件' },
{ key: 5, value: 5, label: '草稿' }, { key: 5, value: 5, label: '草稿' },
{ key: 6, value: 6, label: '垃圾邮件' }, { key: 6, value: 6, label: '垃圾邮件' },
{ key: 7, value: 7, label: '已处理邮件' }, { key: 7, value: 7, label: '已处理邮件' },
] ]

@ -15,7 +15,7 @@ const PAGE_SIZE = 50 // 每页显示条数
const MailBox = ({ mailboxDir, onMailItemClick, ...props }) => { const MailBox = ({ mailboxDir, onMailItemClick, ...props }) => {
const [selectedItems, setSelectedItems] = useState([]) const [selectedItems, setSelectedItems] = useState([])
const { mailList, loading, error, refresh, markAsRead, markAsProcessed, markAsDeleted, searchMailList } = useEmailList(mailboxDir) const { mailList, loading, error, tempBreadcrumb, refresh, markAsRead, markAsProcessed, markAsDeleted, } = useEmailList(mailboxDir)
const [pagination, setPagination] = useState({ const [pagination, setPagination] = useState({
current: 1, current: 1,
@ -127,7 +127,7 @@ const MailBox = ({ mailboxDir, onMailItemClick, ...props }) => {
</Tooltip> </Tooltip>
</Flex> </Flex>
<Flex wrap gap={8}> <Flex wrap gap={8} >
<NewEmailButton /> <NewEmailButton />
<Button <Button
size='small' size='small'
@ -162,20 +162,12 @@ const MailBox = ({ mailboxDir, onMailItemClick, ...props }) => {
删除 删除
</Button> </Button>
<MailOrderSearchModal /> <MailOrderSearchModal />
<MailListSearchModal mailboxDir={mailboxDir} /> <MailListSearchModal />
{/* <Button
size='small'
icon={<DeleteOutlined />}
onClick={() => {
searchMailList()
}}>
查找邮件
</Button> */}
</Flex> </Flex>
</div> </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={(tempBreadcrumb || props.breadcrumb).map((bc) => {
return { return {
title: ( title: (
<> <>

@ -1,30 +1,27 @@
import { createContext, useEffect, useState } from 'react' import { useState } from 'react'
import { ReloadOutlined, ReadOutlined, RightOutlined, LeftOutlined, SearchOutlined, MailOutlined } from '@ant-design/icons' import { SearchOutlined } from '@ant-design/icons'
import { Button, Modal, Form, Input, Checkbox, Select, Radio, Segmented, Divider, Typography, Flex } from 'antd' import { Button, Modal, Form, Input, Radio } from 'antd'
import dayjs from 'dayjs' import { searchEmailListAction } from '@/actions/EmailActions'
import { getEmailDirAction, queryHTOrderListAction, searchEmailListAction } from '@/actions/EmailActions'
import { isEmpty, objectMapper, pick } from '@/utils/commons'
import useConversationStore from '@/stores/ConversationStore' import useConversationStore from '@/stores/ConversationStore'
import { useEmailList } from '@/hooks/useEmail'
const MailListSearchModal = ({ ...props }) => { const MailListSearchModal = ({ ...props }) => {
const [currentMailboxOPI] = useConversationStore((state) => [state.currentMailboxOPI]) const [currentMailboxOPI] = useConversationStore((state) => [state.currentMailboxOPI])
const { searchMailList } = useEmailList(props.mailboxDir)
const [openForm, setOpenForm] = useState(false) const [openForm, setOpenForm] = useState(false)
const [formSearch] = Form.useForm() const [formSearch] = Form.useForm()
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const onSubmitSearchMailList = async (values) => { const onSubmitSearchMailList = async (values) => {
// console.log('Received values of form: ', values)
setLoading(true) setLoading(true)
searchMailList() await searchEmailListAction({...values, opi_sn: currentMailboxOPI});
setLoading(false) setLoading(false)
setOpenForm(false) setOpenForm(false)
} }
return ( return (
<> <>
<Button key={'bound'} onClick={() => setOpenForm(true)} size='small' icon={<SearchOutlined className='' />}> <Button key={'bound'} onClick={() => setOpenForm(true)} size='small' icon={<SearchOutlined className='' />}>
查找订单 查找邮件
</Button> </Button>
<Modal <Modal
width={window.innerWidth < 700 ? '95%' : 960} width={window.innerWidth < 700 ? '95%' : 960}
@ -41,17 +38,17 @@ const MailListSearchModal = ({ ...props }) => {
layout='vertical' layout='vertical'
form={formSearch} form={formSearch}
name='searchmaillist_form_in_modal' name='searchmaillist_form_in_modal'
initialValues={{ mailboxtype: '1' }} initialValues={{ mailboxtype: '' }}
clearOnDestroy clearOnDestroy
onFinish={(values) => onSubmitSearchMailList(values)} onFinish={(values) => onSubmitSearchMailList(values)}
className='[&_.ant-form-item]:m-2'> className='[&_.ant-form-item]:m-2'>
{dom} {dom}
</Form> </Form>
)}> )}>
<Form.Item name='mailboxtype' label='文件夹'> <Form.Item name='mailboxtype' label='邮箱文件夹'>
<Radio.Group <Radio.Group
options={[ options={[
{ key: '-1', value: 'ALL', label: 'All' }, { key: 'All', value: '', label: 'All' },
{ key: '1', value: '1', label: '收件箱' }, { key: '1', value: '1', label: '收件箱' },
{ key: '2', value: '2', label: '未读邮件' }, { key: '2', value: '2', label: '未读邮件' },
{ key: '3', value: '3', label: '已发邮件' }, { key: '3', value: '3', label: '已发邮件' },

@ -1,11 +1,10 @@
import { createContext, useEffect, useState } from 'react' import { useState } from 'react'
import { ReloadOutlined, ReadOutlined, RightOutlined, LeftOutlined, SearchOutlined, MailOutlined } from '@ant-design/icons' import { SearchOutlined } from '@ant-design/icons'
import { Button, Modal, Form, Input, Checkbox, Select, Radio, DatePicker, Divider, Typography, Flex } from 'antd' import { Button, Modal, Form, Input, Checkbox, Radio, DatePicker, Divider, Typography, Flex } from 'antd'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { getEmailDirAction, queryHTOrderListAction, queryInMailboxAction } from '@/actions/EmailActions' import { getEmailDirAction, queryHTOrderListAction, } from '@/actions/EmailActions'
import { isEmpty, objectMapper, pick } from '@/utils/commons' import { isEmpty, objectMapper, pick } from '@/utils/commons'
import useConversationStore from '@/stores/ConversationStore' import useConversationStore from '@/stores/ConversationStore'
import { mailboxSystemDirs } from '@/hooks/useEmail'
const MailOrderSearchModal = ({ ...props }) => { const MailOrderSearchModal = ({ ...props }) => {
const [currentMailboxOPI] = useConversationStore((state) => [state.currentMailboxOPI]) const [currentMailboxOPI] = useConversationStore((state) => [state.currentMailboxOPI])
@ -38,7 +37,7 @@ const MailOrderSearchModal = ({ ...props }) => {
result = await queryHTOrderListAction({ ...htOrderParams, opi_sn: currentMailboxOPI }) result = await queryHTOrderListAction({ ...htOrderParams, opi_sn: currentMailboxOPI })
const addToTree = { const addToTree = {
key: 'search-orders', key: 'search-orders',
title: '搜索结果', title: '查找订单',
iconIndex: 'search', iconIndex: 'search',
_raw: { COLI_SN: 0, IsTrue: 0 }, _raw: { COLI_SN: 0, IsTrue: 0 },
children: result.map((o) => ({ children: result.map((o) => ({
@ -46,7 +45,7 @@ const MailOrderSearchModal = ({ ...props }) => {
title: `${o.COLI_ID}`, title: `${o.COLI_ID}`,
iconIndex: 13, iconIndex: 13,
parent: 'search-orders', parent: 'search-orders',
parentTitle: '搜索结果', parentTitle: '查找订单',
parentIconIndex: 'search', parentIconIndex: 'search',
_raw: { ...o, VKey: o.COLI_SN, VName: o.COLI_ID, VParent: 'search-orders', IsTrue: 0, ApplyDate: '', OrderSourceType: htOrderParams.sourcetype, parent: 'search-orders' }, _raw: { ...o, VKey: o.COLI_SN, VName: o.COLI_ID, VParent: 'search-orders', IsTrue: 0, ApplyDate: '', OrderSourceType: htOrderParams.sourcetype, parent: 'search-orders' },
})), })),

Loading…
Cancel
Save