import { useState, useEffect, useCallback } from 'react' import { isEmpty, objectMapper, olog, readIndexDB, } from '@/utils/commons' import { getEmailDetailAction, postResendEmailAction, getSalesSignatureAction, getEmailOrderAction, queryEmailListAction, getEmailTemplateAction } from '@/actions/EmailActions' import { App } from 'antd' import useConversationStore from '@/stores/ConversationStore'; import { msgStatusRenderMapped } from '@/channel/bubbleMsgUtils'; import { POPUP_FEATURES } from '@/config'; export const useEmailSignature = (opi_sn) => { const [signature, setSignature] = useState('') const getSignature = useCallback(async () => { if (isEmpty(Number(opi_sn))) { return false } try { const data = await getSalesSignatureAction({ opi_sn }) setSignature(data) } catch (err) { console.error(err) } }, [opi_sn]) useEffect(() => { getSignature() }, [getSignature]) return { signature } } /** * @param mai_sn 邮件编号ID * @param data 直接传递, 不重复获取 * * 在详情点击`回复`呼出编辑时 */ export const useEmailDetail = (mai_sn, data={}, oid=0) => { const {notification} = App.useApp() const [loading, setLoading] = useState(false) const [mailData, setMailData] = useState({ loading, info: { MAI_COLI_SN: 0 }, content: '', attachments: [], AttachList: [] }) const [coliSN, setColiSN] = useState(oid); const [orderDetail, setOrderDetail] = useState({}); const [updateMessageItem] = useConversationStore(state => [state.updateMessageItem]); useEffect(() => { const getEmailDetail = async () => { if (isEmpty(Number(mai_sn))) { return false } try { setLoading(true) const data = await getEmailDetailAction({ mai_sn }) // console.log(data) setMailData(data) setColiSN(data.info.MAI_COLI_SN) // if (!isEmpty(data.info.MAI_COLI_SN)) { // const orderData = await getEmailOrderAction({ colisn: data.info.MAI_COLI_SN }) // setOrderDetail(orderData) // // console.log(orderData) // } setLoading(false) } catch (err) { setLoading(false) notification.error({ message: "请求失败", description: err.message || '网络异常', placement: "top", duration: 3, }); } } if (isEmpty(data)) getEmailDetail() else setMailData(data) }, [mai_sn]) useEffect(() => { console.log(coliSN, '====colisn======') const getOrderDetail = async () => { if (isEmpty(coliSN)) { return false } try { setLoading(true) const data = await getEmailOrderAction({ colisn: coliSN }) setOrderDetail(data) setLoading(false) } catch (err) { setLoading(false) notification.error({ message: "请求失败", description: err.message || '网络异常', placement: "top", duration: 3, }); } } getOrderDetail() }, [coliSN]) const postEmailResend = async ({ mai_sn, conversationid: externalid, actionId: actionid, ...body }) => { if (isEmpty(mai_sn)) { return false } await postResendEmailAction({ mai_sn, externalid, actionid, token: 0 }) // 重发没有状态返回值, 此处前端处理为'待发送', todo: 刷新页面后消息仍为上一个状态'失败' updateMessageItem({ conversationid: externalid, actionid, id: actionid, status: msgStatusRenderMapped['accepted'] }) } return { loading, mailData, orderDetail, postEmailResend } } export const EmailBuilder = ({subject, content}) => { return `${content}`; } export const openPopup = (url, target,) => { window.open(url, target, POPUP_FEATURES); }; export const useEmailList = (mailboxDirNode) => { const [loading, setLoading] = useState(false) const [mailList, setMailList] = useState([]) const [error, setError] = useState(null) const [isFreshData, setIsFreshData] = useState(false) const [refreshTrigger, setRefreshTrigger] = useState(0); const refresh = useCallback(() => { setRefreshTrigger(prev => prev + 1); }, []); const { OPI_SN: opi_sn, COLI_SN, VKey, VParent, ApplyDate, OrderSourceType, IsTrue } = mailboxDirNode const getMailList = useCallback(async () => { console.log('getMailList', mailboxDirNode) if (!opi_sn || !VKey || (!IsTrue && !COLI_SN)) { setMailList([]) setLoading(false) setError(null) setIsFreshData(false) return } setLoading(true) setError(null) setIsFreshData(false) const cacheKey = isEmpty(COLI_SN) ? `dir-${VKey}` : `order-${VKey}` const readCache = await readIndexDB(cacheKey, 'maillist', 'mailbox') if (!isEmpty(readCache)) { const _x = readCache.data.map((ele) => ({ ...ele, key: ele.MAI_SN, })) setMailList(_x) setLoading(false) } try { const nodeParam = { coli_sn: COLI_SN, order_source_type: OrderSourceType, vkey: VKey, vparent: VParent, mai_senddate1: ApplyDate } const x = await queryEmailListAction({ opi_sn, node: nodeParam }) // 配合List的结构 const _x = x.map((ele) => ({ ...ele, key: ele.MAI_SN, })) setMailList(_x) } catch (networkError) { setError(new Error(`Failed to get mail list: ${networkError.message}.`)) } finally { setLoading(false) } }, [VKey, refreshTrigger]) useEffect(() => { getMailList() }, [getMailList]) return { loading, isFreshData, error, mailList, refresh } } const orderMailTypes = new Map([ ['48001', '发送一催'], ['48002', '发送二催'], ['48003', '发送三催'], ['48004', '发送已收客人付款通知'], ['48005', '发送FAQ及PreSurvey'], ['48006', '发送降价邮件'], ['48007', '发送亚马逊津贴'], ['48008', '发送报价信'], ['48009', '提交调度'], ['48010', '发送确认信'], ['48011', '发送余款提醒信'], ['48012', '发送入境提醒'], ['48013', '首站关怀'], ['48014', '抵桂面谈'], ['48015', '末站关怀'], ['48016', '发送计划'], ['48017', '报价中'], ['48018', '以后联系'], ['48019', '成行'], ['48020', '团款收讫'], ['48021', '取消'], ['48022', '丢失'], ['48023', '已做计划'], ['48024', '一催回复'], ['48025', '二催回复'], ['48026', '第一次报价回复'], ['48027', '发送商务感谢信'], ['48028', '商务酒店房满邮件'], ['48029', '商务预订传真'], ['48030', '商务取消邮件'], ['48031', '商务单团财务表'], ['48032', '商务收款单'], ['48033', '商务退款单'], ['48034', '商务财务转帐申请'], ['48035', '商务未订先确认'], ['48036', '商务等待确认'], ['48037', '商务已确认'], ['48038', '商务已付款'], ['48039', '商务成功订单'], ['48040', '商务取消订单'], ['48041', '商务不成行订单'], ['48042', '商务已付款未出票'], ['48043', '商务已付款并出票'], ['48044', '商务无效订单'], ['48045', '问候提醒'], ['48046', '发送邮件'], ['48047', '来华一周年问候'], ['48048', '来华二周年提醒'], ['48049', 'CH Phone询问邮件'], ['48050', '订单电话销售'], ['48051', '等待付订金'], ['48052', '商务订单预订中'], ['48053', '客户需求调查'], ['48054', '发送TourCredits通知邮件'], ['48055', 'GH海外PostSurvey'], ]) export const emailTemplates = [ { type: 'RemindOneWL', index: 1, key: '1@RemindOneWL', value: '1@RemindOneWL', label: '一催模板一,询问客人是否收到报价信' }, { type: 'RemindOneWL', index: 2, key: '2@RemindOneWL', value: '2@RemindOneWL', label: '一催模板二,询问客人是否修改行程' }, { type: 'divider' }, { type: 'RemindTwoWL', index: 1, key: '1@RemindTwoWL', value: '1@RemindTwoWL', label: '二催模板一,询问客人对行程的看法' }, { type: 'RemindTwoWL', index: 2, key: '2@RemindTwoWL', value: '2@RemindTwoWL', label: '二催模板二,表达服务的意识' }, { type: 'divider' }, { type: 'RemindThreeWL', index: 1, key: '1@RemindThreeWL', value: '1@RemindThreeWL', label: '三催模板三,强调价格有效期' }, ]; export const emailTemplateMap = emailTemplates.reduce((acc, cur) => { if (cur.type === 'divider') { return acc } acc[cur.key] = cur return acc }, {}); /** * * @param {object} params - Parameters for the email template request. * @param {number} [params.coli_sn] - Customer order line item serial number. * @param {number} [params.lgc] - Language code. * @param {number} [params.opi_sn] - Order product item serial number. */ export const useEmailTemplate = (templateKey, params) => { const [loading, setLoading] = useState(false) const [error, setError] = useState(null) const [templateContent, setTemplateContent] = useState({ mailtype: '', mailtypeName: '', subject: '', mailcontent: '' }) const getTemplateContent = useCallback(async () => { if (!templateKey || !Number(params.coli_sn) || !Number(params.opi_sn)) { setTemplateContent({ mailtype: '', mailtypeName: '', subject: '', mailcontent: '' }) setLoading(false) setError(null) return } setLoading(true) setError(null) try { const { index: remind_index, type: remind_type } = emailTemplateMap[templateKey] || {}; const _params = { ...params, remind_index, remind_type}; const x = await getEmailTemplateAction(_params) const lowerCaseShallow = Object.keys(x).reduce((acc, key) => ({...acc, [key.toLowerCase()]: x[key]}), {}) setTemplateContent({...lowerCaseShallow, mailtypeName: orderMailTypes.get(lowerCaseShallow.mailtype)}) } catch (networkError) { setError(new Error(`Failed to get template content: ${networkError.message}.`)) } finally { setLoading(false) } }, [templateKey, params.opi_sn, params.coli_sn, params.lgc]) useEffect(() => { getTemplateContent() }, [getTemplateContent]) return { loading, error, templateContent }; }