|
|
@@ -0,0 +1,381 @@
|
|
|
+import React, { useEffect, useState } from "react";
|
|
|
+import style from './index.less';
|
|
|
+import { Avatar, Button, DatePicker, Drawer, Input, Modal, Popover, Select, Space, Table, Tag, Typography } from "antd";
|
|
|
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
|
+import { faUserFriends } from "@fortawesome/free-solid-svg-icons";
|
|
|
+import { getProjectGroupsAllListApi } from "../../API/groupManage";
|
|
|
+import { useAjax } from "@/Hook/useAjax";
|
|
|
+import { getTransferLogListApi, GetTransferLogListProps } from "../../API/logs";
|
|
|
+import SearchBox from "../../components/searchBox";
|
|
|
+import { ExclamationCircleOutlined, QuestionCircleFilled, SearchOutlined } from '@ant-design/icons';
|
|
|
+import dayJs from "dayjs";
|
|
|
+import useNewToken from "@/Hook/useNewToken";
|
|
|
+import { copy } from "@/utils/utils";
|
|
|
+import FilterUserTooltip from "../../components/filterUser/filterUserTooltip";
|
|
|
+import { EUTTaskStatus, TIME_TYPE_ZJ } from "../businessPlan/create/const";
|
|
|
+import PreviewTime from "../../components/previewTime";
|
|
|
+import Log from "../businessPlan/taskList/components/externalUserTransferTask/log";
|
|
|
+const { Text } = Typography;
|
|
|
+
|
|
|
+interface Props {
|
|
|
+ taskTotal: number;
|
|
|
+ todayAddTask: number;
|
|
|
+ todayFinishTaskRate: number;
|
|
|
+ todayFailTask: number,
|
|
|
+ bookPlatForm: TASK_CREATE.BookPlatFormProps[]
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 客户继承
|
|
|
+ * @param param0
|
|
|
+ * @returns
|
|
|
+ */
|
|
|
+const TransferItem: React.FC<Props> = ({ taskTotal, todayAddTask, todayFinishTaskRate, todayFailTask, bookPlatForm }) => {
|
|
|
+
|
|
|
+ /******************************************/
|
|
|
+ const { token } = useNewToken()
|
|
|
+ const [visible, setVisible] = useState<boolean>(false)
|
|
|
+ const [groupList, setGroupList] = useState<{ label: string, value: number }[]>([]);
|
|
|
+ const [queryParams, setQueryParams] = useState<GetTransferLogListProps>({ pageNum: 1, pageSize: 20 })
|
|
|
+ const [oldQueryParams, setOldQueryParams] = useState<GetTransferLogListProps>({ pageNum: 1, pageSize: 20 })
|
|
|
+ const [modal, contextHolder] = Modal.useModal();
|
|
|
+ const [logVisible, setLogVisible] = useState<boolean>(false)
|
|
|
+ const [logData, setLogData] = useState<{ taskId: number, taskName: string }>()
|
|
|
+
|
|
|
+ const getProjectGroupsAllList = useAjax(() => getProjectGroupsAllListApi())
|
|
|
+ const getTransferLogList = useAjax((params) => getTransferLogListApi(params))
|
|
|
+ /******************************************/
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (visible) {
|
|
|
+ getProjectGroupsAllList.run().then(res => {
|
|
|
+ setGroupList([{ label: '空项目组', value: 0 }, ...res?.data?.map(item => ({ label: item.name, value: item.id })) || []])
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }, [visible])
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (visible) {
|
|
|
+ getTransferLogList.run(queryParams)
|
|
|
+ }
|
|
|
+ }, [queryParams, visible])
|
|
|
+
|
|
|
+ const lookLog = (value: any) => {
|
|
|
+ setLogData({ taskId: value.id, taskName: value.taskName })
|
|
|
+ setLogVisible(true)
|
|
|
+ }
|
|
|
+
|
|
|
+ return <>
|
|
|
+ {contextHolder}
|
|
|
+ <div className={style.moduleCard} onClick={() => setVisible(true)}>
|
|
|
+ <div className={style.moduleCard_header}>
|
|
|
+ <Avatar style={{ backgroundColor: '#e6fffb', color: '#36cfc9' }} size={30}>
|
|
|
+ <FontAwesomeIcon icon={faUserFriends} />
|
|
|
+ </Avatar>
|
|
|
+ 客户继承
|
|
|
+ </div>
|
|
|
+ <div className={style.moduleCard_center}>
|
|
|
+ 总任务数:{taskTotal || 0} | 今日新增:{todayAddTask || 0}
|
|
|
+ </div>
|
|
|
+ <div className={style.moduleCard_footer}>
|
|
|
+ <span>今日完成率:{((todayFinishTaskRate || 0) * 100).toFixed(2)} %</span>
|
|
|
+ <span className={style.error}>今日异常:{todayFailTask}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <Drawer
|
|
|
+ title={'客户继承'}
|
|
|
+ onClose={() => setVisible(false)}
|
|
|
+ open={visible}
|
|
|
+ width={'70%'}
|
|
|
+ >
|
|
|
+ <SearchBox
|
|
|
+ bodyPadding={`0 0 10px`}
|
|
|
+ buttons={<>
|
|
|
+ <Button type="primary" onClick={() => {
|
|
|
+ setQueryParams({ ...oldQueryParams, pageNum: 1, pageSize: queryParams.pageSize })
|
|
|
+ }} loading={getTransferLogList.loading} icon={<SearchOutlined />}>搜索</Button>
|
|
|
+ </>}
|
|
|
+ >
|
|
|
+ <>
|
|
|
+ <Input
|
|
|
+ placeholder="任务名称"
|
|
|
+ style={{ width: 120 }}
|
|
|
+ allowClear
|
|
|
+ onChange={(e) => setOldQueryParams({ ...oldQueryParams, projectName: e.target.value })}
|
|
|
+ value={oldQueryParams?.projectName}
|
|
|
+ />
|
|
|
+ <Input
|
|
|
+ placeholder="子任务ID"
|
|
|
+ style={{ width: 120 }}
|
|
|
+ allowClear
|
|
|
+ onChange={(e) => setOldQueryParams({ ...oldQueryParams, taskId: e.target.value })}
|
|
|
+ value={oldQueryParams?.taskId}
|
|
|
+ />
|
|
|
+ <Select
|
|
|
+ showSearch
|
|
|
+ style={{ minWidth: 100 }}
|
|
|
+ allowClear
|
|
|
+ onChange={(value) => {
|
|
|
+ setOldQueryParams({ ...oldQueryParams, status: value })
|
|
|
+ }}
|
|
|
+ value={oldQueryParams?.status}
|
|
|
+ placeholder="发送状态"
|
|
|
+ filterOption={(input, option) =>
|
|
|
+ ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
|
|
|
+ }
|
|
|
+ options={[{ label: '创建中', value: 0 }, { label: '执行中', value: 1 }, { label: '已发送', value: 2 }, { label: '暂停', value: 3 }]}
|
|
|
+ />
|
|
|
+ <Select
|
|
|
+ placeholder='请选择项目组'
|
|
|
+ allowClear
|
|
|
+ options={groupList}
|
|
|
+ showSearch
|
|
|
+ maxTagCount={1}
|
|
|
+ style={{ minWidth: 150 }}
|
|
|
+ filterOption={(input, option) =>
|
|
|
+ (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
|
|
|
+ }
|
|
|
+ mode="multiple"
|
|
|
+ value={oldQueryParams?.projectGroupIds}
|
|
|
+ onChange={(value) => setOldQueryParams({ ...oldQueryParams, projectGroupIds: value })}
|
|
|
+ />
|
|
|
+ <DatePicker
|
|
|
+ placeholder="发送开始时间"
|
|
|
+ onChange={(e, date) => { setOldQueryParams({ ...oldQueryParams, startDay: date as string }) }}
|
|
|
+ allowClear
|
|
|
+ value={oldQueryParams?.startDay ? dayJs(oldQueryParams?.startDay) : undefined}
|
|
|
+ />
|
|
|
+ <DatePicker
|
|
|
+ placeholder="发送结束时间"
|
|
|
+ onChange={(e, date) => { setOldQueryParams({ ...oldQueryParams, endDay: date as string }) }}
|
|
|
+ allowClear
|
|
|
+ value={oldQueryParams?.endDay ? dayJs(oldQueryParams?.endDay) : undefined}
|
|
|
+ />
|
|
|
+ </>
|
|
|
+ </SearchBox>
|
|
|
+
|
|
|
+ {/* 表 */}
|
|
|
+ <Table
|
|
|
+ style={{ marginTop: 10 }}
|
|
|
+ dataSource={getTransferLogList?.data?.data?.records}
|
|
|
+ loading={getTransferLogList?.loading}
|
|
|
+ bordered
|
|
|
+ columns={[
|
|
|
+ {
|
|
|
+ title: '操作',
|
|
|
+ dataIndex: 'cz',
|
|
|
+ key: 'cz',
|
|
|
+ width: 100,
|
|
|
+ align: 'center',
|
|
|
+ render: (_, record: any) => {
|
|
|
+ return <Space>
|
|
|
+ <a onClick={() => {
|
|
|
+ modal.confirm({
|
|
|
+ title: '确认',
|
|
|
+ icon: <ExclamationCircleOutlined />,
|
|
|
+ content: '是否跳转到日志详情?',
|
|
|
+ okText: '确认',
|
|
|
+ cancelText: '复制',
|
|
|
+ onCancel: () => {
|
|
|
+ copy(record.projectName + '任务Id:' + record.taskId)
|
|
|
+ },
|
|
|
+ onOk: () => {
|
|
|
+ localStorage.setItem('OPENTASK', JSON.stringify({
|
|
|
+ id: record.projectId,
|
|
|
+ projectName: record.projectName,
|
|
|
+ taskType: 'TASK_STAT_TRANSFER',
|
|
|
+ taskId: record.taskId,
|
|
|
+ msg: '跳转日志详情'
|
|
|
+ }))
|
|
|
+ window.open(`/weComTask#/weComTask/businessPlan/taskList`)
|
|
|
+ },
|
|
|
+ });
|
|
|
+ }}>任务跳转</a>
|
|
|
+ {[1, 2].includes(record?.taskStatus) && <a onClick={() => { lookLog(record) }}>日志</a>}
|
|
|
+ </Space>
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '任务名称',
|
|
|
+ dataIndex: 'projectName',
|
|
|
+ key: 'projectName',
|
|
|
+ width: 180,
|
|
|
+ ellipsis: true,
|
|
|
+ render: (text) => <a onClick={() => copy(text)}>{text}</a>
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '子任务ID',
|
|
|
+ dataIndex: 'id',
|
|
|
+ key: 'id',
|
|
|
+ width: 70,
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '项目组名称',
|
|
|
+ dataIndex: 'projectGroupName',
|
|
|
+ key: 'projectGroupName',
|
|
|
+ width: 100,
|
|
|
+ ellipsis: true,
|
|
|
+ align: 'center',
|
|
|
+ render: (text) => text ? <a onClick={() => copy(text)}>{text}</a> : '--'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '项目组ID',
|
|
|
+ dataIndex: 'projectGroupId',
|
|
|
+ key: 'projectGroupId',
|
|
|
+ width: 70,
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '任务名称',
|
|
|
+ dataIndex: 'taskName',
|
|
|
+ key: 'taskName',
|
|
|
+ width: 180,
|
|
|
+ ellipsis: true,
|
|
|
+ align: 'center',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '企业ID',
|
|
|
+ dataIndex: 'corpId',
|
|
|
+ key: 'corpId',
|
|
|
+ width: 150,
|
|
|
+ ellipsis: true,
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '接替人员',
|
|
|
+ dataIndex: 'takeoverUserName',
|
|
|
+ key: 'takeoverUserName',
|
|
|
+ align: 'center',
|
|
|
+ width: 100,
|
|
|
+ ellipsis: true,
|
|
|
+ render: (text: string) => text || '--'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '原跟进成员',
|
|
|
+ dataIndex: 'corpUserId',
|
|
|
+ key: 'corpUserId',
|
|
|
+ width: 100,
|
|
|
+ ellipsis: true,
|
|
|
+ align: 'center',
|
|
|
+ render(value) {
|
|
|
+ return value || '--'
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '任务提交状态',
|
|
|
+ dataIndex: 'taskStatus',
|
|
|
+ key: 'taskStatus',
|
|
|
+ width: 100,
|
|
|
+ ellipsis: true,
|
|
|
+ align: 'center',
|
|
|
+ render(value) {
|
|
|
+ return EUTTaskStatus[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}
|
|
|
+ />
|
|
|
+ </div>}
|
|
|
+ styles={{ body: { width: 300, overflow: 'hidden', overflowY: 'auto', maxHeight: 400 } }}
|
|
|
+ >
|
|
|
+ <a style={{ color: '#000' }}><QuestionCircleFilled /></a>
|
|
|
+ </Popover>}
|
|
|
+ </>
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '继承对象',
|
|
|
+ dataIndex: 'siftPopulationConfigContentDTO',
|
|
|
+ key: 'siftPopulationConfigContentDTO',
|
|
|
+ width: 100,
|
|
|
+ align: 'center',
|
|
|
+ render(value) {
|
|
|
+ return value ? <div className={style.nameBox}>
|
|
|
+ <div>
|
|
|
+ <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={value?.configName}
|
|
|
+ data={value}
|
|
|
+ />}
|
|
|
+ >
|
|
|
+ <a style={{ color: '#000' }}><QuestionCircleFilled /></a>
|
|
|
+ </Popover>
|
|
|
+ </div> : '全部'
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '继承成功发送文案',
|
|
|
+ dataIndex: 'transferSuccessMsg',
|
|
|
+ key: 'transferSuccessMsg',
|
|
|
+ width: 150,
|
|
|
+ ellipsis: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '创建人',
|
|
|
+ dataIndex: 'createByName',
|
|
|
+ key: 'createByName',
|
|
|
+ width: 100,
|
|
|
+ ellipsis: true,
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '创建时间',
|
|
|
+ dataIndex: 'createTime',
|
|
|
+ key: 'createTime',
|
|
|
+ width: 135,
|
|
|
+ ellipsis: true,
|
|
|
+ align: 'center'
|
|
|
+ }
|
|
|
+ ]}
|
|
|
+ scroll={{ x: 1000 }}
|
|
|
+ rowKey={'id'}
|
|
|
+ size='small'
|
|
|
+ onRow={(row: any) => {
|
|
|
+ return !row?.status ? {
|
|
|
+ style: { background: token.colorPrimaryBgHover }
|
|
|
+ } : {}
|
|
|
+ }}
|
|
|
+ pagination={{
|
|
|
+ total: getTransferLogList?.data?.data?.total,
|
|
|
+ showTotal: (total) => <Tag color="cyan">总共{total}数据</Tag>,
|
|
|
+ showSizeChanger: true,
|
|
|
+ showLessItems: true,
|
|
|
+ defaultCurrent: 1,
|
|
|
+ defaultPageSize: 200,//默认初始的每页条数
|
|
|
+ current: getTransferLogList?.data?.data?.current || 1,
|
|
|
+ pageSize: getTransferLogList?.data?.data?.size || 20,
|
|
|
+ onChange: (page, pageSize) => {
|
|
|
+ setQueryParams({ ...queryParams, pageNum: page, pageSize })
|
|
|
+ setOldQueryParams({ ...oldQueryParams, pageNum: page, pageSize })
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </Drawer>
|
|
|
+
|
|
|
+ {/* 日志 */}
|
|
|
+ {(logVisible && logData) && <Log {...logData} visible={logVisible} onClose={() => { setLogVisible(false); setLogData(undefined) }} />}
|
|
|
+ </>
|
|
|
+};
|
|
|
+
|
|
|
+export default React.memo(TransferItem);
|