123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509 |
- import { useAjax } from "@/Hook/useAjax"
- import { getProjectLogDetailsListApi, getProjectLogListApi, getProjectTaskLogCountApi, getProjectTaskLogListApi } from "@/pages/weComTask/API/groupChat"
- import FilterUserTooltip from "@/pages/weComTask/components/filterUser/filterUserTooltip";
- import { Badge, Button, Drawer, Flex, Modal, Popover, Space, Table, Typography } from "antd"
- import React, { useEffect, useState } from "react"
- import { QuestionCircleFilled } from "@ant-design/icons"
- import { businessPlanData, LQTaskStatus, TIME_TYPE_ZJ } from "../../businessPlan/create/const";
- import PreviewTime from "@/pages/weComTask/components/previewTime";
- const { Text, Paragraph, Title } = Typography;
- interface Props {
- data: any,
- bookPlatForm: TASK_CREATE.BookPlatFormProps[]
- bookList: TASK_CREATE.BookListProps[]
- visible?: boolean,
- onClose?: () => void,
- }
- const Details: React.FC<Props> = ({ data, bookPlatForm, bookList, visible, onClose }) => {
- /*******************************************/
- const getProjectLogList = useAjax((params) => getProjectLogListApi(params))
- /*******************************************/
- useEffect(() => {
- getProjectLogList.run(data.id)
- }, [])
- return <Drawer
- title={<Space>
- <strong>{data.taskName} 运营计划</strong>
- <Button type="link" onClick={() => getProjectLogList.refresh()}>刷新</Button>
- </Space>}
- onClose={onClose}
- open={visible}
- width={1400}
- styles={{ body: { paddingTop: 5 } }}
- >
- <Table
- size='small'
- bordered
- rowKey={'id'}
- dataSource={getProjectLogList?.data?.data || []}
- scroll={{ y: 1000 }}
- columns={[
- {
- title: '任务名称',
- dataIndex: 'taskName',
- key: 'taskName',
- width: 180,
- ellipsis: true,
- fixed: 'left'
- },
- {
- title: '群名称',
- dataIndex: 'groupName',
- key: 'groupName',
- width: 120,
- ellipsis: true,
- fixed: 'left'
- },
- {
- title: '计划状态',
- dataIndex: 'taskStatus',
- key: 'taskStatus',
- width: 90,
- align: 'center',
- fixed: 'left',
- render(value) {
- return LQTaskStatus[value] || '--'
- },
- },
- {
- title: '执行时间',
- dataIndex: 'timeRepeatType',
- key: 'timeRepeatType',
- width: 100,
- ellipsis: true,
- align: 'center',
- render(value, records: any) {
- return <>
- {TIME_TYPE_ZJ[value] || '--'}
- {value !== 'TIME_TYPE_SINGLE_TIMELY' && <Popover
- placement="left"
- content={<div>
- <PreviewTime
- {...records}
- sendTime={records?.sendTime || records?.repeatSendTime}
- />
- </div>}
- styles={{ body: { width: 300, overflow: 'hidden', overflowY: 'auto', maxHeight: 400 } }}
- >
- <a style={{ color: '#000' }}><QuestionCircleFilled /></a>
- </Popover>}
- </>
- },
- },
- {
- title: '是否开启已有旧群聊补缺',
- dataIndex: 'isRepair',
- key: 'isRepair',
- width: 150,
- ellipsis: true,
- render(value, record: any) {
- return value ? <Space>
- <Badge status="success" text="开启" />
- <span>近{record.repairTimes}天</span>
- </Space> : <Badge status="error" text="关闭" />
- },
- },
- {
- title: '进群对象',
- dataIndex: 'corpCondition',
- key: 'corpCondition',
- width: 90,
- align: 'center',
- render(value) {
- return !value?.[0]?.allCorpUser ? <div style={{ display: 'flex', alignItems: 'center' }}>
- <div style={{ flex: '1 0', overflow: 'hidden' }}>
- <Text ellipsis>指定</Text>
- </div>
- <Popover
- placement="right"
- styles={{ body: { maxWidth: 350, maxHeight: 350, overflow: 'hidden', overflowY: 'auto' } }}
- mouseEnterDelay={0.5}
- content={<FilterUserTooltip
- bookCityList={bookPlatForm?.map(item => ({ label: item.platformName, value: item.platformKey }))}
- configName={'进群对象'}
- data={value?.[0]}
- />}
- >
- <a style={{ color: '#000' }}><QuestionCircleFilled /></a>
- </Popover>
- </div> : '全部'
- },
- },
- {
- title: '群递增起始编号',
- dataIndex: 'groupIndex',
- key: 'groupIndex',
- width: 60,
- align: 'center'
- },
- {
- title: '群固定人数',
- dataIndex: 'groupUserCount',
- key: 'groupUserCount',
- width: 50,
- align: 'center'
- },
- {
- title: '邀请客户进群完毕后客服号是否退群',
- dataIndex: 'autoOutGroup',
- key: 'autoOutGroup',
- width: 85,
- align: 'center',
- render(value) {
- return value ? <span style={{ color: '#1890ff' }}>是</span> : <span style={{ color: 'red' }}>否</span>
- },
- },
- {
- title: '是否排除已在群的客户',
- dataIndex: 'excludeInGroup',
- key: 'excludeInGroup',
- width: 60,
- align: 'center',
- render(value) {
- return value ? <span style={{ color: '#1890ff' }}>是</span> : <span style={{ color: 'red' }}>否</span>
- },
- },
- {
- title: '拉群完成后自动删除拉群标签',
- dataIndex: 'excludeInGroup',
- key: 'excludeInGroup',
- width: 70,
- align: 'center',
- render(value) {
- return value ? <span style={{ color: '#1890ff' }}>是</span> : <span style={{ color: 'red' }}>否</span>
- },
- },
- {
- title: '群聊关联公众号',
- dataIndex: 'mpAccountInfo',
- key: 'mpAccountInfo',
- width: 100,
- align: 'center',
- ellipsis: true,
- render(value) {
- return value?.name || '--'
- },
- },
- {
- title: '拉群完成后群聊备注',
- dataIndex: 'remark',
- key: 'remark',
- width: 140,
- ellipsis: true,
- render(value) {
- return value || '--'
- },
- },
- {
- title: '拉群完成后群聊智能标签',
- dataIndex: 'msgTagDTO',
- key: 'msgTagDTO',
- width: 200,
- ellipsis: true,
- render(value) {
- return value && Object.keys(value)?.length > 0 ?
- <Paragraph ellipsis style={{ margin: 0 }}>{Object.keys(value).map(key => {
- if (key === 'business' && value[key]) {
- return `业务(来源渠道):${businessPlanData.find(i => i.value === value.business)?.label || '<空>'}`
- } else if (key === 'bookCity' && value[key]) {
- return `书城(来源渠道):${bookPlatForm.find(i => i.id === value.bookCity)?.platformName || '<空>'}`
- } else if (key === 'product' && value[key]) {
- return `产品(来源渠道):${bookList.find(i => i.id === value.product)?.bookName || '<空>'}`
- }
- return ''
- }).join('、')}</Paragraph> : '--'
- },
- },
- {
- title: '建群成功发送内容',
- dataIndex: 'groupSendMsg',
- key: 'groupSendMsg',
- width: 140,
- ellipsis: true,
- render(value) {
- return value ? value : '--'
- },
- },
- {
- title: '创建人',
- dataIndex: 'createBy',
- key: 'createBy',
- width: 80,
- align: 'center',
- ellipsis: true,
- render(value) {
- return value?.nickname || '--'
- }
- }
- ]}
- expandable={{
- fixed: 'left',
- expandRowByClick: true,
- expandedRowRender: (record) => <ExpandedRow record={record} />
- }}
- />
- </Drawer>
- }
- const ExpandedRow: React.FC<{ record: any }> = ({ record }) => {
- /*****************************************/
- const [detalisData, setDetalisData] = useState<{ visible?: boolean, taskLogId?: number }>()
- const [queryForm, setQueryForm] = useState<{ pageNum: number, pageSize: number }>({ pageNum: 1, pageSize: 20 })
- const [failedUserDetails, setFailedUserDetails] = useState<{ visible?: boolean, list: any[] }>({ visible: false, list: [] })
- const [total, setTotal] = useState<{ pullGroupCount?: number, pullGroupUserCount?: number, pullGroupUserSuccessCount?: number, pullSuccessCount?: number }>({})
- const getProjectTaskLogList = useAjax((params) => getProjectTaskLogListApi(params))
- const getProjectTaskLogCount = useAjax((params) => getProjectTaskLogCountApi(params))
- /*****************************************/
- useEffect(() => {
- getProjectTaskLogList.run({ ...queryForm, taskId: record.id })
- }, [record.id, queryForm])
- useEffect(() => {
- getProjectTaskLogCount.run(record.id).then(res => {
- setTotal(res?.data || {})
- })
- }, [record.id, queryForm])
- return <div style={{ maxHeight: 450 }}>
- <Flex gap={20} align="center" style={{ marginBottom: 10, marginTop: 5 }}>
- <Title level={4} style={{ margin: 0 }}>{record?.taskName} 任务列表</Title>
- <Button type="link" onClick={() => getProjectTaskLogList.refresh()}>刷新</Button>
- <Text strong>预计拉群数:{total?.pullGroupCount || 0}</Text>
- <Text strong>预计拉群客户数:{total?.pullGroupUserCount || 0}</Text>
- <Text strong>拉群成功总客户数:{total?.pullGroupUserSuccessCount || 0}</Text>
- <Text strong>拉群成功总数数:{total?.pullSuccessCount || 0}</Text>
- </Flex>
- <Table
- size='small'
- bordered
- rowKey={'id'}
- dataSource={getProjectTaskLogList?.data?.data?.records}
- loading={getProjectTaskLogList.loading}
- scroll={{ x: 400, y: 350 }}
- columns={[
- {
- title: '操作',
- dataIndex: 'cz',
- key: 'cz',
- width: 80,
- align: 'center',
- render(_, record: any) {
- return <a onClick={() => setDetalisData({ visible: true, taskLogId: record.id })}>详情</a>
- }
- },
- {
- title: '预计拉群数',
- dataIndex: 'pullGroupCount',
- key: 'pullGroupCount',
- width: 120
- },
- {
- title: '预计拉群客户数',
- dataIndex: 'pullGroupUserCount',
- key: 'pullGroupUserCount',
- width: 120
- },
- {
- title: '上次失败补拉数量',
- dataIndex: 'lastFailedRetryCount',
- key: 'lastFailedRetryCount',
- width: 120
- },
- {
- title: '实际拉群客户数',
- dataIndex: 'pullSuccessUserCount',
- key: 'pullSuccessUserCount',
- width: 120
- },
- {
- title: '实际拉群数',
- dataIndex: 'pullSuccessCount',
- key: 'pullSuccessCount',
- width: 120
- },
- {
- title: '失败客户数',
- dataIndex: 'pullFailedUserCount',
- key: 'pullFailedUserCount',
- width: 120,
- render: (a, b) => {
- return <a onClick={() => setFailedUserDetails({ visible: true, list: b?.pullFailedUserDetail || [] })}>{a}</a>
- }
- },
- {
- title: '执行时间',
- dataIndex: 'createTime',
- key: 'createTime'
- }
- ]}
- pagination={{
- total: getProjectTaskLogList?.data?.data?.total || 0,
- current: queryForm.pageNum,
- pageSize: queryForm.pageSize,
- showTotal: (total) => `共 ${total} 条数据`,
- onChange: (pageNum, pageSize) => setQueryForm({ pageNum, pageSize })
- }}
- />
- {/* 详情 */}
- {detalisData?.visible && <TaskDetails
- {...detalisData}
- onClose={() => setDetalisData(undefined)}
- />}
- {/* 失败客户详情 */}
- {failedUserDetails?.visible && <FailedUserDetails
- {...failedUserDetails}
- onClose={() => setFailedUserDetails({ visible: false, list: [] })}
- />}
- </div>
- }
- const TaskDetails: React.FC<{
- visible?: boolean,
- taskLogId?: number,
- onClose?: () => void
- }> = ({ visible, taskLogId, onClose }) => {
- /*******************************************/
- const getProjectLogDetailsList = useAjax((params) => getProjectLogDetailsListApi(params))
- /*******************************************/
- useEffect(() => {
- getProjectLogDetailsList.run(taskLogId)
- }, [taskLogId])
- return <Modal
- title={<strong>任务详情</strong>}
- open={visible}
- onCancel={onClose}
- width={900}
- footer={null}
- >
- <Table
- size='small'
- bordered
- rowKey={'id'}
- dataSource={getProjectLogDetailsList?.data?.data || []}
- scroll={{ y: 1000 }}
- columns={[
- {
- title: '群名称',
- dataIndex: 'chatName',
- key: 'chatName',
- width: 120,
- ellipsis: true,
- },
- {
- title: '群主号名称',
- dataIndex: 'corpUserName',
- key: 'corpUserName',
- width: 120,
- ellipsis: true,
- },
- {
- title: '预计拉群客户数',
- dataIndex: 'pullGroupUserCount',
- key: 'pullGroupUserCount',
- width: 80,
- align: 'center'
- },
- {
- title: '实际拉群客户数',
- dataIndex: 'actualPullGroupUserCount',
- key: 'actualPullGroupUserCount',
- width: 80,
- align: 'center'
- },
- {
- title: '删除或拉黑客户数',
- dataIndex: 'deleteOrBlockUserCount',
- key: 'deleteOrBlockUserCount',
- width: 80,
- align: 'center'
- }
- ]}
- />
- </Modal>
- }
- const FailedUserDetails: React.FC<{
- visible?: boolean,
- list?: any[],
- onClose?: () => void
- }> = ({ visible, list, onClose }) => {
- return <Modal
- title={<strong>任务详情</strong>}
- open={visible}
- onCancel={onClose}
- width={900}
- footer={null}
- >
- <Table
- size='small'
- bordered
- rowKey={'externalUserId'}
- dataSource={list || []}
- scroll={{ y: 1000 }}
- columns={[
- {
- title: '企业名称',
- dataIndex: 'corpName',
- key: 'corpName',
- width: 120,
- ellipsis: true,
- },
- {
- title: '企业ID',
- dataIndex: 'corpId',
- key: 'corpId',
- width: 120,
- ellipsis: true,
- },
- {
- title: '客服名称',
- dataIndex: 'corpUserName',
- key: 'corpUserName',
- width: 120,
- ellipsis: true,
- },
- {
- title: '客服ID',
- dataIndex: 'corpUserId',
- key: 'corpUserId',
- width: 120,
- ellipsis: true,
- },
- {
- title: '客服名称',
- dataIndex: 'name',
- key: 'name',
- width: 120,
- ellipsis: true,
- },
- {
- title: '客户ID',
- dataIndex: 'externalUserId',
- key: 'externalUserId',
- width: 120,
- ellipsis: true,
- }
- ]}
- />
- </Modal>
- }
- export default React.memo(Details)
|