|
|
import { Link } from 'react-router-dom'
|
|
|
import { Form, Input, Button, DatePicker, Select, Table } from 'antd'
|
|
|
import dayjs from 'dayjs'
|
|
|
import { ReadIcon, DeliverIcon, SentIcon, WaitingIcon, FailedIcon, ReplyIcon } from '@/components/Icons'
|
|
|
import { MessageTwoTone } from '@ant-design/icons'
|
|
|
import useCustomerRelationStore from '@/stores/CustomerRelationStore'
|
|
|
|
|
|
const { RangePicker } = DatePicker
|
|
|
const { Option } = Select
|
|
|
|
|
|
// 消息状态
|
|
|
const statusIconMap = {
|
|
|
read: <ReadIcon title='read' />,
|
|
|
delivered: <DeliverIcon title='delivered' />,
|
|
|
sent: <SentIcon title='sent' />,
|
|
|
failed: <FailedIcon title='failed' />,
|
|
|
accepted: <WaitingIcon title='accepted' />,
|
|
|
default: <WaitingIcon title='waiting' />,
|
|
|
}
|
|
|
|
|
|
const Index = () => {
|
|
|
const { loading, tasksList, fetchSearchTasks } = useCustomerRelationStore()
|
|
|
|
|
|
// 定义默认值
|
|
|
const initialFormValues = {
|
|
|
crt_coli_id: '', // 客人名字默认空
|
|
|
dateRange: [dayjs().startOf('M'), dayjs().endOf('M')], // 默认本月
|
|
|
crt_status: '', // 状态默认所有
|
|
|
}
|
|
|
|
|
|
// 搜索表单提交
|
|
|
const onFinish = (values) => {
|
|
|
const formattedValues = {
|
|
|
...values,
|
|
|
start_date: values.dateRange ? values.dateRange[0].format('YYYY-MM-DD') : '',
|
|
|
end_date: values.dateRange ? values.dateRange[1].endOf('day').format('YYYY-MM-DD HH:mm:ss') : '',
|
|
|
}
|
|
|
fetchSearchTasks(formattedValues)
|
|
|
}
|
|
|
|
|
|
// 按 crt_template 分组并统计每个非空 msg_status 的数量
|
|
|
const templateStatusCount = {}
|
|
|
tasksList.forEach((item) => {
|
|
|
const { crt_template, msg_status, msg_reply } = item
|
|
|
if (msg_status !== null && msg_status !== undefined) {
|
|
|
if (!templateStatusCount[crt_template]) {
|
|
|
templateStatusCount[crt_template] = {}
|
|
|
templateStatusCount[crt_template]['msgreply'] = 0
|
|
|
}
|
|
|
if (!templateStatusCount[crt_template][msg_status]) {
|
|
|
templateStatusCount[crt_template][msg_status] = 0
|
|
|
}
|
|
|
templateStatusCount[crt_template][msg_status]++
|
|
|
|
|
|
if (msg_reply) {
|
|
|
templateStatusCount[crt_template]['msgreply']++
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
|
|
|
// 计算分组后的百分比并添加计数
|
|
|
const groupedResult = {}
|
|
|
for (const template in templateStatusCount) {
|
|
|
//总数需要减去msgreply的数量,msgreply是状态之外的数据
|
|
|
const total = Object.values(templateStatusCount[template]).reduce((acc, val) => acc + val, 0) - templateStatusCount[template]['msgreply']
|
|
|
groupedResult[template] = {}
|
|
|
for (const status in templateStatusCount[template]) {
|
|
|
const count = templateStatusCount[template][status]
|
|
|
const percentage = ((count / total) * 100).toFixed(2)
|
|
|
groupedResult[template][`${status}_count`] = count
|
|
|
groupedResult[template][`${status}_percentage`] = `${percentage}%`
|
|
|
}
|
|
|
console.log(groupedResult)
|
|
|
}
|
|
|
|
|
|
// 将 groupedResult 转换为表格可用的数据格式
|
|
|
const groupedData = Object.entries(groupedResult).map(([template, stats]) => {
|
|
|
return {
|
|
|
key: template,
|
|
|
crt_template: template,
|
|
|
...stats,
|
|
|
}
|
|
|
})
|
|
|
|
|
|
// 动态生成表格列
|
|
|
const groupedColumns = []
|
|
|
groupedColumns.push({
|
|
|
title: '模板名称',
|
|
|
dataIndex: 'crt_template',
|
|
|
key: 'crt_template',
|
|
|
})
|
|
|
|
|
|
const allStatuses = new Set(['msgreply'])
|
|
|
tasksList.forEach((item) => {
|
|
|
if (item.msg_status !== null && item.msg_status !== undefined) {
|
|
|
allStatuses.add(item.msg_status)
|
|
|
}
|
|
|
})
|
|
|
|
|
|
// 将 Set 转换为数组并排序
|
|
|
const sortedStatuses = Array.from(allStatuses).sort()
|
|
|
|
|
|
sortedStatuses.forEach((status) => {
|
|
|
groupedColumns.push({
|
|
|
title: `${status} 计数`,
|
|
|
dataIndex: `${status}_count`,
|
|
|
key: `${status}_count`,
|
|
|
})
|
|
|
groupedColumns.push({
|
|
|
title: `${status} 百分比`,
|
|
|
dataIndex: `${status}_percentage`,
|
|
|
key: `${status}_percentage`,
|
|
|
})
|
|
|
})
|
|
|
|
|
|
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 columns = [
|
|
|
{ title: '团号', dataIndex: 'crt_coli_id', key: 'crt_coli_id' },
|
|
|
{ title: '客人', dataIndex: 'crt_mei_firstname', key: 'crt_mei_firstname', render: (text, record) => record.crt_mei_firstname + ' ' + record.crt_mei_lastname },
|
|
|
{ title: '国家', dataIndex: 'crt_coi2_country', key: 'crt_coi2_country' },
|
|
|
// { title: '时区', dataIndex: 'ct_coi_code', key: 'ct_coi_code' },
|
|
|
|
|
|
{
|
|
|
title: '状态',
|
|
|
dataIndex: 'crt_status',
|
|
|
key: 'crt_status',
|
|
|
render: (status) => {
|
|
|
if (status == '0') {
|
|
|
return '待发送'
|
|
|
} else if (status == '99') {
|
|
|
return '已发送'
|
|
|
}
|
|
|
return '失败'
|
|
|
},
|
|
|
},
|
|
|
{ title: '发送时间', dataIndex: 'crt_send_datetime', key: 'crt_send_datetime', sorter: (a, b) => dayjs(a.crt_send_datetime).unix() - dayjs(b.crt_send_datetime).unix() },
|
|
|
{ title: '模板', dataIndex: 'crt_template', key: 'crt_template' },
|
|
|
{ title: 'WhatsApp', dataIndex: 'crt_whatsapp', key: 'crt_whatsapp' },
|
|
|
{
|
|
|
title: '会话',
|
|
|
dataIndex: 'crt_conversation_id',
|
|
|
key: 'crt_conversation_id',
|
|
|
render: (text, record) => {
|
|
|
if (text) {
|
|
|
const icon = statusIconMap[record.msg_status] || statusIconMap['default']
|
|
|
return (
|
|
|
<Link to={`/order/chat/${record.crt_coli_sn}`} title={record.errors_code ? record.errors_code + '' + record.errors_title : ''}>
|
|
|
查看会话 {icon} {record.msg_reply ? <MessageTwoTone title='已回复' /> : ''}
|
|
|
</Link>
|
|
|
)
|
|
|
}
|
|
|
},
|
|
|
},
|
|
|
// { title: '消息ID', dataIndex: 'crt_message_id', key: 'crt_message_id' },
|
|
|
// { title: '邮箱', dataIndex: 'crt_mei_maillist', key: 'crt_mei_maillist' },
|
|
|
// { title: '创建时间', dataIndex: 'ct_datetime', key: 'ct_datetime' },
|
|
|
// { title: '客人国家', dataIndex: 'crt_mei_country', key: 'crt_mei_country' },
|
|
|
]
|
|
|
|
|
|
return (
|
|
|
<>
|
|
|
{/* 搜索栏 */}
|
|
|
<Form layout='inline' onFinish={onFinish} style={{ marginBottom: 24 }} initialValues={initialFormValues}>
|
|
|
<Form.Item label='团号' name='crt_coli_id'>
|
|
|
<Input placeholder='输入团号' />
|
|
|
</Form.Item>
|
|
|
<Form.Item label='任务时间' name='dateRange'>
|
|
|
<RangePicker allowClear={true} inputReadOnly={true} presets={DATE_RANGE_PRESETS} />
|
|
|
</Form.Item>
|
|
|
<Form.Item label='状态' name='crt_status'>
|
|
|
<Select placeholder='请选择状态' style={{ width: 120 }}>
|
|
|
<Option value=''>所有</Option>
|
|
|
<Option value='0'>待发送</Option>
|
|
|
<Option value='99'>已发送</Option>
|
|
|
</Select>
|
|
|
</Form.Item>
|
|
|
<Form.Item>
|
|
|
<Button type='primary' htmlType='submit'>
|
|
|
搜索
|
|
|
</Button>
|
|
|
</Form.Item>
|
|
|
</Form>
|
|
|
|
|
|
<span>搜索结果总数: {tasksList && tasksList.length}</span>
|
|
|
|
|
|
<Table dataSource={tasksList} columns={columns} pagination={false} rowKey='crt_sn' loading={loading} />
|
|
|
<h2>统计结果</h2>
|
|
|
<Table dataSource={groupedData} columns={groupedColumns} pagination={false} loading={loading} />
|
|
|
</>
|
|
|
)
|
|
|
}
|
|
|
|
|
|
export default Index
|