import { groupBy, isNotEmpty, pick, sortArrayByOrder, sortBy } from '@/utils/commons'; import { fetchJSON, postJSON, postForm } from '@/utils/request' import { parseRenderMessageList } from '@/channel/bubbleMsgUtils'; import { API_HOST } from '@/config'; import { isEmpty } from '@/utils/commons'; import dayjs from 'dayjs'; /** * @param {object} params { waba } */ export const fetchTemplates = async (params) => { const data = await fetchJSON(`${API_HOST}/listtemplates`, params); const topName = [ 'agent_intro_with_update_v1', 'online_inquiry_received', 'say_hello_again', 'order_updated_specialist_assigned_christy', 'order_resumed_specialist_followup_schedule_sharon', 'travel_service_update_v2', 'travel_service_update_v1', 'order_updated_specialist_assigned_sharon', 'first_message_for_not_reply', // 'free_style_3', // 'free_style_4', ]; // shouwcase const scNames = ['trip_planner_showcase', 'showcase_different', 'order_status_updated']; // 客运 const crNames = [ // 'notification_of_following_up_by_cr_v3', 'notification_of_one_day_before_ending_the_trip_by_cr_v2', 'one_day_after_payment_by_yuni', 'notification_of_status_changed', 'notification_of_one_day_before_ending_the_trip_by_cr','one_day_after_payment_by_customer_relations', 'one_day_before_ending_the_trip_contacted_by_yuni','one_day_before_ending_the_trip_first_time_by_yuni', 'post_booking_confirmation_welcome', ]; const crNamesOmit = [ 'birthday_greetings_by_marketing','one_day_before_ending_the_trip_by_marketing', 'introduce_the_voucher_one_day_before_ending_the_trip_by_marketing', 'birthday_greetings_by_customer_relations_0', 'post_trip_voucher_issued', 'account_updated_order_ref', 'post_trip_account_updated_from_cr', 'post_trip_account_updated', 'account_update_birthday', 'post_trip_birthday_reward', 'birthday_greetings_by_customer_relations_2', 'birthday_greetings_by_customer_relations_1', 'notification_of_account_updated_by_cr', 'birthday_greetings_by_customer_relations', 'one_day_before_ending_the_trip_by_customer_relations', ] const canUseTemplates = (data?.result?.items || []) .filter((_t) => _t.status === 'APPROVED' && !['say_hello_from_trip_advisor', 'free_style_7', 'free_style_1', 'free_style_2'].includes(_t.name)) .map((ele, i) => ({ ...ele, components_origin: ele.components, components: groupBy(ele.components, (_c) => _c.type.toLowerCase()), key: ele.name, // displayName: ele.name.startsWith('order_updated') ? templatesDisplayNameMap['order_updated']+`_${i}` : templatesDisplayNameMap?.[ele.name] || ele.name, displayName: templatesDisplayNameMap?.[ele.name] || (ele.name.startsWith('order_updated') ? templatesDisplayNameMap['order_updated']+`_${i}` : ele.name), displayLanguage: crNamesOmit.includes(ele.name) ? '客运-' : (crNames.includes(ele.name) || ele.name.includes('by_cr')) ? ele.language + '-客运' : scNames.includes(ele.name) ? ele.language + '-示例' : ele.language, })) const top2Name = topName.concat(canUseTemplates.filter(_t => _t.name.startsWith('order_updated')).map(_tem => _tem.name)); const top = sortArrayByOrder( canUseTemplates.filter((_t) => top2Name.includes(_t.name)), 'name', topName); const second = canUseTemplates.filter(_t => _t.name.includes('free_style')); const secondS = second.sort(sortBy('name')); const raw = canUseTemplates.filter((_t) => !top2Name.includes(_t.name) && !_t.name.includes('free_style')); // 剩下的排序 const rawS = sortArrayByOrder(raw, 'name', [...crNames, ...scNames, ...crNamesOmit ]); return [...top, ...secondS, ...rawS]; }; /** * ↑上面的模板名称bak * order_updated_specialist_assigned_sharon : free_style_7 * order_updated_specialist_assigned_christy : free_style_1 * online_inquiry_received: say_hello_from_trip_advisor * order_resumed_specialist_followup_schedule_sharon: free_style_2 */ const templatesDisplayNameMap = { 'order_updated_specialist_assigned_sharon': 'specialist_followup', 'order_updated_specialist_assigned_christy': 'specialist_followup_1', 'online_inquiry_received': 'online_inquiry_received/say_hello', 'order_resumed_specialist_followup_schedule_sharon': 'order_resumed/specialist_followup', 'order_updated': 'specialist_followup', 'agent_intro_with_update_v1': 'quick_update_v1', }; export const CONVERSATION_PAGE_SIZE = 100; /** * * @param {object} params { opisn } */ export const fetchConversationsList = async (params) => { const defaultParams = { opisn: '', pagesize: CONVERSATION_PAGE_SIZE, lastpagetime: '', tags: '', olabel: '', keyword: '', ostate: '', intour: '', session_enable: 1, lastactivetime: '', top_state: '', } const combinedFilterStr = Object.values(pick(params, ['keyword', 'tags', 'olabel', 'intour', 'ostate'])).join('') if (isNotEmpty(combinedFilterStr) || params.session_enable === 0) { params.lastactivetime = ''; } const { errcode, result: data } = await fetchJSON(`${API_HOST}/getconversations`, { ...defaultParams, ...params }) if (errcode !== 0) return []; const list = (data || []).map((ele) => ({ ...ele, customer_name: `${ele.whatsapp_name || ''}`.trim(), whatsapp_name: `${ele.whatsapp_name || ''}`.trim(), show_default: ele.conversation_memo || ele.whatsapp_name || ele?.channels?.whatsapp_phone_number || ele?.channels?.phone_number || ele?.channels?.email || '', // coli_id: ele.COLI_ID, top_state: ele.top_state || 0, })) return list; }; /** * * @param {object} params { opisn, whatsappid, colisn, email } * * opisn, colisn : 用于查询 * * whatsappid, email: 用于创建会话 */ export const fetchOrderConversationsList = async (params) => { const { errcode, result: data } = await fetchJSON(`${API_HOST}/getorderconversation`, params); if (errcode !== 0) return []; const list = data.map((ele) => ({ ...ele, customer_name: `${ele.whatsapp_name || ''}`.trim(), whatsapp_name: `${ele.whatsapp_name || ''}`.trim(), show_default: ele.conversation_memo || ele.whatsapp_name || ele?.channels?.whatsapp_phone_number || ele?.channels?.phone_number || ele?.channels?.email || '', })) return list; }; export const MESSAGE_PAGE_SIZE = 50; /** * * @param {object} params { coli_sn, opisn, whatsappid, conversationid, lasttime, pagesize } */ export const fetchMessages = async (params) => { const defaultParams = { // opisn: '', // whatsappid: '', coli_sn: '', conversationid: '', lasttime: '', pagesize: MESSAGE_PAGE_SIZE, }; const { errcode, result } = await fetchJSON(`${API_HOST}/getcusmessages`, {...defaultParams, ...params}); return errcode !== 0 ? [] : parseRenderMessageList((result || []).reverse()); } /** * * @param {object} body { opisn, conversationid } */ export const fetchConversationItemClose = async (body) => { const { result } = await fetchJSON(`${API_HOST}/closeconversation`, body); return result; }; /** * @param {object} body { phone_number, name } */ export const postNewOrEditConversationItem = async (body) => { body.whatsapp_phone_number = `${body.whatsapp_phone_number || ''}`.trim(); const formData = new FormData(); Object.keys(body).forEach(function (key) { formData.append(key, body[key]); }); const { errcode, result } = await postForm(`${API_HOST}/new_conversation`, formData); if (errcode !== 0) { return {}; } const resultItem = result?.[0] || {}; return { ...resultItem, customer_name: `${resultItem.whatsapp_name || ''}`.trim(), whatsapp_name: `${resultItem.whatsapp_name || ''}`.trim(), // channels: {}, // tags: [], // last_message: {}, top_state: 0, // conversation_memo: resultItem.session_memo, }; }; /** * @param {object} params { conversationid, coli_sn } */ export const postEditConversationItemColiAction = async (params) => { const { errcode, result } = await fetchJSON(`${API_HOST}/update_conversation_orderid`, params); return errcode !== 0 ? {} : result; }; /** * @param {object} params { opisn, conversationid } */ export const fetchCleanUnreadMsgCount = async (params) => { const { errcode, result } = await fetchJSON(`${API_HOST}/clean_unread_msg_count`, params); return errcode !== 0 ? {} : result; }; /** * 标记未未读 * @param {object} body conversationItem: { sn, ... } */ export const UNREAD_MARK = 999; export const fetchConversationItemUnread = async (body) => { const { errcode, result } = await fetchJSON(`${API_HOST}/set_state_unread`, body); return errcode !== 0 ? {} : result; }; /** * 设置置顶 * @param {object} body { conversationid, top_state } */ export const fetchConversationItemTop = async (body) => { const { errcode, result } = await fetchJSON(`${API_HOST}/set_top_conversation`, body); return errcode !== 0 ? {} : result; }; /** * ------------------------------------------------------------------------------------------------ * 历史记录 */ /** * @param {object} params { search, from_date, end_date, whatsapp_id, opisn, coli_id, msg_type } * @todo msg_type */ export const fetchConversationsSearch = async (params) => { const { errcode, result: data } = await fetchJSON(`${API_HOST}/conversation_search`, params); const list = errcode !== 0 ? [] : (data || []).map((ele) => ({ ...ele, sn: ele.conversationid, customer_name: `${ele.whatsapp_name || ''}`.trim(), whatsapp_name: `${ele.whatsapp_name || ''}`.trim(), opi_sn: ele.OPI_SN || ele.opi_sn || 0, OPI_Name: `${ele.OPI_Name || ele.opi_name || ''}`.trim(), opi_name: `${ele.OPI_Name || ele.opi_name || ''}`.trim(), dateText: dayjs((ele.lasttime)).format('MM-DD HH:mm'), matchMsgList: parseRenderMessageList((ele.msglist_AsJOSN || [])), // .reverse()), coli_id: '', show_default: ele.session_memo || ele.whatsapp_name || ele?.whatsapp_phone_number || ele?.guest_email || '', })); return list; }; /** * * @param {object} params { opisn, whatsappid, lasttime, pagesize, pagedir } */ export const fetchMessagesHistory = async (params) => { const defaultParams = { // opisn: '', // whatsappid: '', conversationid: '', lasttime: '2024-01-01T00:00:00', pagesize: MESSAGE_PAGE_SIZE, pagedir: 'next', }; const _params = pick(params, Object.keys(defaultParams)); if (isEmpty(_params.conversationid)) { return []; } const { errcode, result } = await fetchJSON(`${API_HOST}/get_item_messages`, {...defaultParams, ..._params}); const data = errcode !== 0 ? [] : result; // _params.pagedir === 'next' ? result.reverse() : result; return parseRenderMessageList(data); } /** * @param {object} params { opisn, phone_number_from, phone_number_mergeto } */ export const fetchConversationMerge = async (params) => { const { errcode, result } = await fetchJSON(`${API_HOST}/merge_session`, params); return errcode !== 0 ? {} : result; }; /** * ------------------------------------------------------------------------------------------------ * 未分配 */ export const fetchConversationsUnassigned = async (params) => { const { errcode, result: data } = await fetchJSON(`${API_HOST}/unassigned-conversation`, params); const list = errcode !== 0 ? [] : (data || []).map((ele) => ({ ...ele, customer_name: `${ele.whatsapp_name || ''}`.trim(), whatsapp_name: `${ele.whatsapp_name || ''}`.trim(), opi_sn: ele.OPI_SN || ele.opi_sn || 0, OPI_Name: `${ele.OPI_Name || ele.opi_name || ''}`.trim(), dateText: dayjs((ele.last_received_time)).format('MM-DD HH:mm'), })); return list; }; /** * @param {object} params { opi_sn, conversationid } */ export const postAssignConversation = async (params) => { const { errcode, result } = await fetchJSON(`${API_HOST}/assign_conversation`, params); return errcode !== 0 ? {} : result; } /** * ------------------------------------------------------------------------------------------------ * */ /** * 顾问的自定义标签 * @param {object} params { opisn, } */ export const fetchTags = async (params) => { const { errcode, result } = await fetchJSON(`${API_HOST}/get_opi_tags`, params); return errcode !== 0 ? [] : result.map(ele => ({ label: ele.tag_label, key: ele.tag_key, value: ele.tag_key, })); } /** * 会话设置标签 * @param {object} body { opisn, conversationid, tag_label, tag_id } */ export const postConversationTags = async (body) => { const formData = new FormData(); Object.keys(body).forEach(function (key) { formData.append(key, body[key]); }); const { errcode, result } = await postForm(`${API_HOST}/set_conversation_tags_add`, formData); return errcode !== 0 ? {} : result[0]; } /** * 会话删除标签 * @param {object} params { opisn, conversationid, tag_id } */ export const deleteConversationTags = async (params) => { const { errcode, result } = await fetchJSON(`${API_HOST}/set_conversation_tags_del`, params); return errcode !== 0 ? {} : result; }