wjx vor 1 Tag
Ursprung
Commit
8e1f834c5a

+ 26 - 0
src/pages/weComTask/API/logs/index.tsx

@@ -120,4 +120,30 @@ export function getSendUserLogListApi(data: GetSendUserLogListProps) {
         method: 'POST',
         data
     })
+}
+
+export interface GetSendRobotLogListProps {
+    pageNum: number,
+    pageSize: number,
+    projectName?: string,
+    taskId?: any,
+    status?: 0 | 2,
+    expectStartDay?: string,
+    expectEndDay?: string
+    startDay?: string,
+    endDay?: string
+    projectGroupIds?: number[]
+}
+
+/**
+ * 机器人转发记录
+ * @param data 
+ * @returns 
+ */
+export function getSendRobotLogListApi(data: GetSendRobotLogListProps) {
+    return request({
+        url: api + `/corpOperation/corp/stats/listOfPage/send/robot/log`,
+        method: 'POST',
+        data
+    })
 }

+ 1 - 1
src/pages/weComTask/page/groupChatSend/robot/taskList/components/groupTask/shareTabls.tsx

@@ -12,7 +12,7 @@ interface Props {
     taskId: number,
 }
 
-function msToHMS(ms) {
+export function msToHMS(ms) {
     const totalSeconds = Math.floor(ms / 1000);
     const hours = Math.floor(totalSeconds / 3600);
     const minutes = Math.floor((totalSeconds % 3600) / 60);

+ 347 - 25
src/pages/weComTask/page/home/groupItem.tsx

@@ -5,7 +5,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { IconDefinition } from "@fortawesome/free-solid-svg-icons";
 import { getProjectGroupsAllListApi } from "../../API/groupManage";
 import { useAjax } from "@/Hook/useAjax";
-import { getSendUserListApi, GetSendUserListProps, getSendUserLogListApi, GetSendUserLogListProps } from "../../API/logs";
+import { getSendRobotLogListApi, getSendUserListApi, GetSendUserListProps, getSendUserLogListApi, GetSendUserLogListProps } from "../../API/logs";
 import SearchBox from "../../components/searchBox";
 import { ExclamationCircleOutlined, InfoCircleOutlined, QuestionCircleOutlined, SearchOutlined } from "@ant-design/icons";
 import dayJs from "dayjs";
@@ -14,6 +14,7 @@ import { copy } from "@/utils/utils";
 import GroupErrorCountList from "../businessPlan/taskList/components/groupTask/groupErrorCountList";
 import PreviewMsg from "../../components/previewMsg";
 import { emoList } from "../../components/textEditor/Expression";
+import { msToHMS } from "../groupChatSend/robot/taskList/components/groupTask/shareTabls";
 
 
 interface IProps {
@@ -37,10 +38,12 @@ const GroupItem: React.FC<IProps> = ({ title, icon, taskTotal, todayAddTask, tod
     /***********************************************/
 
     useEffect(() => {
-        getProjectGroupsAllList.run().then(res => {
-            setGroupList([{ label: '空项目组', value: 0 }, ...res?.data?.map(item => ({ label: item.name, value: item.id })) || []])
-        })
-    }, [])
+        if (visible) {
+            getProjectGroupsAllList.run().then(res => {
+                setGroupList([{ label: '空项目组', value: 0 }, ...res?.data?.map(item => ({ label: item.name, value: item.id })) || []])
+            })
+        }
+    }, [visible])
 
     return <>
         <div className={style.moduleCard} onClick={() => setVisible(true)}>
@@ -72,22 +75,35 @@ const GroupItem: React.FC<IProps> = ({ title, icon, taskTotal, todayAddTask, tod
                 }}
                 activeKey={activeKey}
                 type="card"
-                items={[
-                    {
-                        key: '2',
-                        label: '下发企微号',
-                        children: <>
-                            {activeKey == '2' && <GroupXfCorpTabls groupList={groupList} projectType={projectType} />}
-                        </>
-                    },
-                    {
-                        key: '4',
-                        label: '群发记录',
-                        children: <>
-                            {activeKey == '4' && <GroupTaskNotes groupList={groupList} projectType={projectType} />}
-                        </>
+                items={(projectType === 2 ? ['2', '4', '5'] : ['2', '4']).map(item => {
+
+                    switch (item) {
+                        case '2':
+                            return {
+                                key: '2',
+                                label: '下发企微号',
+                                children: <>
+                                    {activeKey == '2' && <GroupXfCorpTabls groupList={groupList} projectType={projectType} />}
+                                </>
+                            }
+                        case '4':
+                            return {
+                                key: '4',
+                                label: '群发记录',
+                                children: <>
+                                    {activeKey == '4' && <GroupTaskNotes groupList={groupList} projectType={projectType} />}
+                                </>
+                            }
+                        case '5':
+                            return {
+                                key: '5',
+                                label: '转发记录',
+                                children: <>
+                                    {activeKey == '5' && <ShareTabls groupList={groupList} projectType={projectType} />}
+                                </>
+                            }
                     }
-                ]}
+                })}
             />
 
         </Drawer>
@@ -410,7 +426,11 @@ const GroupXfCorpTabls: React.FC<{ groupList: { label: string, value: number }[]
     </div>
 }
 
-
+/**
+ * 群发记录
+ * @param param0 
+ * @returns 
+ */
 const GroupTaskNotes: React.FC<{ groupList: { label: string, value: number }[], projectType?: 1 | 2 }> = ({ groupList, projectType }) => {
 
     /***********************************/
@@ -616,11 +636,12 @@ const GroupTaskNotes: React.FC<{ groupList: { label: string, value: number }[],
                     align: 'center'
                 },
                 {
-                    title: '任务ID',
-                    dataIndex: 'taskId',
-                    key: 'taskId',
+                    title: '企业名称',
+                    dataIndex: 'corpName',
+                    key: 'corpName',
                     align: 'center',
-                    width: 65
+                    width: 150,
+                    ellipsis: true
                 },
                 {
                     title: '客服号名称',
@@ -721,4 +742,305 @@ const GroupTaskNotes: React.FC<{ groupList: { label: string, value: number }[],
     </div>
 }
 
+/**
+ * 机器人转发记录
+ * @param param0 
+ * @returns 
+ */
+const ShareTabls: React.FC<{ groupList: { label: string, value: number }[], projectType?: 1 | 2 }> = ({ groupList, projectType }) => {
+
+    /***********************************/
+    const taskType = projectType === 1 ? 'TASK_STAT_GROUP_SEND_CHAT' : projectType === 2 ? 'TASK_STAT_GROUP_ROBOT' : 'TASK_STAT_GROUP_SEND'
+    const [queryParams, setQueryParams] = useState<GetSendUserListProps>({ pageNum: 1, pageSize: 20 })
+    const [oldQueryParams, setOldQueryParams] = useState<GetSendUserListProps>({ pageNum: 1, pageSize: 20 })
+    const { token } = useNewToken()
+    const [modal, contextHolder] = Modal.useModal();
+
+    const getSendRobotLogList = useAjax((params) => getSendRobotLogListApi(params))
+    /***********************************/
+
+    useEffect(() => {
+        getSendRobotLogList.run({ ...queryParams, projectType })
+    }, [queryParams, projectType])
+
+    return <div>
+        {contextHolder}
+        <SearchBox
+            bodyPadding={`0 0 10px`}
+            buttons={<>
+                <Button type="primary" onClick={() => {
+                    setQueryParams({ ...oldQueryParams, pageNum: 1, pageSize: queryParams.pageSize })
+                }} loading={getSendRobotLogList.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: <Badge status="default" text='未确认发送' />, value: 0 }, { label: <Badge status="error" text='发送失败' />, value: 1 }, { label: <Badge status="success" text='已确定发送' />, value: 2 }]}
+                />
+                <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}
+                />
+                <DatePicker.RangePicker
+                    placeholder={['预计送达时间(起始)', '预计送达时间(结束)']}
+                    onChange={(e, date) => { setOldQueryParams({ ...oldQueryParams, expectStartDay: date[0], expectEndDay: date[1] }) }}
+                    allowClear
+                    value={oldQueryParams?.expectStartDay ? [dayJs(oldQueryParams?.expectStartDay), dayJs(oldQueryParams?.expectEndDay)] : undefined}
+                />
+            </>
+        </SearchBox>
+
+
+        {/* 表 */}
+        <Table
+            style={{ marginTop: 10 }}
+            dataSource={getSendRobotLogList?.data?.data?.records}
+            loading={getSendRobotLogList?.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,
+                                            taskId: record.taskId,
+                                            msg: '跳转日志详情'
+                                        }))
+                                        switch (taskType) {
+                                            case 'TASK_STAT_GROUP_SEND_CHAT': // 官方群群发
+                                                window.open(`/weComTask#/weComTask/groupChatSend/official/taskList`)
+                                                break
+                                            case 'TASK_STAT_GROUP_ROBOT': // 机器人群发
+                                                window.open(`/weComTask#/weComTask/groupChatSend/robot/taskList`)
+                                                break
+                                            case 'TASK_STAT_GROUP_SEND': // 官方群发
+                                                window.open(`/weComTask#/weComTask/businessPlan/taskList`)
+                                                break
+                                        }
+                                    },
+                                });
+                            }}>任务跳转</a>
+                        </Space>
+                    }
+                },
+                {
+                    title: '任务名称',
+                    dataIndex: 'projectName',
+                    key: 'projectName',
+                    width: 180,
+                    ellipsis: true,
+                    render: (text) => <a onClick={() => copy(text)}>{text}</a>
+                },
+                {
+                    title: '子任务ID',
+                    dataIndex: 'taskId',
+                    key: 'taskId',
+                    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: 'corpName',
+                    key: 'corpName',
+                    align: 'center',
+                    width: 120,
+                    ellipsis: true
+                },
+                {
+                    title: '企微号',
+                    dataIndex: 'userName',
+                    key: 'userName',
+                    align: 'center',
+                    width: 150,
+                    ellipsis: true,
+                    render: (a: string, b: any) => {
+                        return b?.userId + `(${a})`
+                    }
+                },
+                {
+                    title: '发送开始时间',
+                    dataIndex: 'createTime',
+                    key: 'createTime',
+                    align: 'center',
+                    width: 140,
+                    ellipsis: true,
+                },
+                {
+                    title: '发送结束时间',
+                    dataIndex: 'sendTime',
+                    key: 'sendTime',
+                    align: 'center',
+                    width: 140,
+                    ellipsis: true,
+                    render(value) {
+                        return value || '--'
+                    },
+                },
+                {
+                    title: '任务耗时',
+                    dataIndex: 'timeClac',
+                    key: 'timeClac',
+                    align: 'center',
+                    width: 100,
+                    ellipsis: true,
+                    render: (_: any, b: any) => {
+                        let hm, pj
+                        if (b?.sendTime && b?.createTime) {
+                            hm = new Date(b?.sendTime).getTime() - new Date(b?.createTime).getTime()
+                            pj = hm / b?.userCount / 1000
+                        }
+
+                        return hm ? <>{msToHMS(hm)}<br />{pj?.toFixed(1)}秒/群</> : "--"
+                    }
+                },
+                {
+                    title: '发送状态',
+                    dataIndex: 'status',
+                    key: 'status',
+                    align: 'center',
+                    width: 100,
+                    render: (a: number) => {
+                        return { '0': <Badge status='default' text='未确认发送' />, '1': <Badge status="error" text='发送失败' />, '2': <Badge status="success" text='已确认发送' /> }[a] || '--'
+                    }
+                },
+                {
+                    title: '发送数',
+                    dataIndex: 'userCount',
+                    key: 'userCount',
+                    align: 'center',
+                    width: 100,
+                    render: (a: number, b: any) => {
+                        return b?.status == "1" ? 0 : a
+                    }
+                },
+                {
+                    title: '失败用户/群',
+                    dataIndex: 'errChatNameList',
+                    key: 'errChatNameList',
+                    align: 'center',
+                    width: 200,
+                    ellipsis: true,
+                    render: (a: any) => {
+                        return a
+                    }
+                },
+                {
+                    title: '失败原因',
+                    dataIndex: "errorMsg",
+                    align: 'center',
+                    width: 200,
+                    ellipsis: true,
+                    render: (a: string, b: any) => {
+                        return b?.status == "1" ? a : ""
+                    }
+                }
+            ]}
+            scroll={{ x: 1000 }}
+            rowKey={'id'}
+            size='small'
+            onRow={(row: any) => {
+                return !row?.status ? {
+                    style: { background: token.colorPrimaryBgHover }
+                } : {}
+            }}
+            pagination={{
+                total: getSendRobotLogList?.data?.data?.total,
+                showTotal: (total) => <Tag color="cyan">总共{total}数据</Tag>,
+                showSizeChanger: true,
+                showLessItems: true,
+                defaultCurrent: 1,
+                defaultPageSize: 200,//默认初始的每页条数
+                current: getSendRobotLogList?.data?.data?.current || 1,
+                pageSize: getSendRobotLogList?.data?.data?.size || 20,
+                onChange: (page, pageSize) => {
+                    setQueryParams({ ...queryParams, pageNum: page, pageSize })
+                    setOldQueryParams({ ...oldQueryParams, pageNum: page, pageSize })
+                }
+            }}
+        />
+    </div>
+}
+
+
 export default React.memo(GroupItem);

+ 6 - 4
src/pages/weComTask/page/home/pullGroup.tsx

@@ -53,10 +53,12 @@ const PullGroup: React.FC<Props> = ({ pullFailCount, pullGroupCount, pullSuccess
     }, [queryParams, visible])
 
     useEffect(() => {
-        getProjectGroupsAllList.run().then(res => {
-            setGroupList([{ label: '空项目组', value: 0 }, ...res?.data?.map(item => ({ label: item.name, value: item.id })) || []])
-        })
-    }, [])
+        if (visible) {
+            getProjectGroupsAllList.run().then(res => {
+                setGroupList([{ label: '空项目组', value: 0 }, ...res?.data?.map(item => ({ label: item.name, value: item.id })) || []])
+            })
+        }
+    }, [visible])
 
     return <>
         {contextHolder}