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.
354 lines
13 KiB
JavaScript
354 lines
13 KiB
JavaScript
|
|
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 = 50;
|
|
/**
|
|
*
|
|
* @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;
|
|
}
|