| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399 |
- import React, { useState, useEffect } from 'react'
- import ProTable from '@ant-design/pro-table'
- import { Row, Col, Divider, Select } from 'antd'
- import { AddressBook, City, Finance, Comment } from '@icon-park/react'
- import { DualAxes } from '@ant-design/charts'
- import consts from '@/consts'
- import { useModal } from '@/components/Modal'
- import { queryDashboard } from '@/services/dashboard'
- import ReminderList from './components/ReminderList'
- import LeaderBoard from './components/LeaderBoard'
- const Dashboard = () => {
- const { Option } = Select
- const [state, setState] = useState({
- visible: false,
- reminderData: [],
- leaderboard: [],
- clientChainRatio: {},
- customerChainRatio: {},
- businessChainRatio: {},
- serviceLogChainRatio: {},
- aggregation: {},
- char: [],
- thread: []
- })
- const { toggleModal, setModalProps } = useModal()
- // 展示服务弹窗详情
- const handleReminderList = (dataType, reminderCyclical) => {
- setModalProps({
- width: '90vw',
- modalRender: () => <ReminderList dataType={dataType} reminderCyclical={reminderCyclical} />,
- onCancel: () => toggleModal()
- })
- toggleModal()
- }
- const initData = async payload => {
- const {
- code = -1,
- data: {
- reminderData = [],
- leaderboard = [],
- clientChainRatio = {},
- customerChainRatio = {},
- businessChainRatio = {},
- serviceLogChainRatio = {},
- aggregation = {},
- char = [],
- thread = []
- }
- } = await queryDashboard(payload)
- if (code === consts.RET_CODE.SUCCESS) {
- setState({
- ...state,
- reminderData,
- leaderboard,
- clientChainRatio,
- customerChainRatio,
- businessChainRatio,
- serviceLogChainRatio,
- aggregation,
- char,
- thread
- })
- }
- }
- useEffect(() => {
- initData()
- }, [])
- const columns = [
- {
- title: '超过周期未服务提醒',
- dataIndex: 'name'
- },
- {
- title: '7天',
- dataIndex: 'day7',
- render: (name, record) => (
- // console.log(record)
- <span
- onClick={() => handleReminderList(record.type, '7day')}
- className="text-primary cursor-pointer hover:text-[#967bbd]">
- {name}
- </span>
- )
- },
- {
- title: '15天',
- dataIndex: 'day15',
- render: (name, record) => (
- <span
- onClick={() => handleReminderList(record.type, '15day')}
- className="text-primary cursor-pointer hover:text-[#967bbd]">
- {name}
- </span>
- )
- },
- {
- title: '30天',
- dataIndex: 'day30',
- render: (name, record) => (
- <span
- onClick={() => handleReminderList(record.type, '30day')}
- className="text-primary cursor-pointer hover:text-[#967bbd]">
- {name}
- </span>
- )
- },
- {
- title: '3个月',
- dataIndex: 'month3',
- render: (name, record) => (
- <span
- onClick={() => handleReminderList(record.type, '3month')}
- className="text-primary cursor-pointer hover:text-[#967bbd]">
- {name}
- </span>
- )
- },
- {
- title: '6个月',
- dataIndex: 'month6',
- render: (name, record) => (
- <span
- onClick={() => handleReminderList(record.type, '6month')}
- className="text-primary cursor-pointer hover:text-[#967bbd]">
- {name}
- </span>
- )
- },
- {
- title: '提醒逾期',
- dataIndex: 'remind',
- render: (name, record) => (
- <span
- onClick={() => handleReminderList(record.type, 'reminder')}
- className="text-primary cursor-pointer hover:text-[#967bbd]">
- {name}
- </span>
- )
- }
- ]
- const charData = state.char
- const threadData = state.thread
- // const uvBillData = [
- // {
- // time: '验证阶段',
- // value: 350,
- // type: '上个月'
- // },
- // {
- // time: '开发阶段',
- // value: 900,
- // type: '上个月'
- // },
- // {
- // time: '提案阶段',
- // value: 300,
- // type: '上个月'
- // },
- // {
- // time: '赢单',
- // value: 450,
- // type: '上个月'
- // },
- // {
- // time: '输单',
- // value: 470,
- // type: '上个月'
- // },
- // {
- // time: '验证阶段',
- // value: 220,
- // type: '本月'
- // },
- // {
- // time: '开发阶段',
- // value: 300,
- // type: '本月'
- // },
- // {
- // time: '提案阶段',
- // value: 250,
- // type: '本月'
- // },
- // {
- // time: '赢单',
- // value: 220,
- // type: '本月'
- // },
- // {
- // time: '输单',
- // value: 362,
- // type: '本月'
- // }
- // ]
- // const transformData = [
- // {
- // time: '验证阶段',
- // 增幅: 800
- // },
- // {
- // time: '开发阶段',
- // 增幅: 600
- // },
- // {
- // time: '提案阶段',
- // 增幅: 400
- // },
- // {
- // time: '赢单',
- // 增幅: 380
- // },
- // {
- // time: '输单',
- // 增幅: 220
- // }
- // ]
- const config = {
- data: [charData, threadData],
- height: 230,
- xField: 'time',
- yField: ['value', '增幅'],
- geometryOptions: [
- {
- geometry: 'column',
- isGroup: true,
- seriesField: 'type',
- color: ['#A088C4', '#605B67']
- },
- {
- geometry: 'line',
- lineStyle: { lineWidth: 2 },
- color: '#FEB51A'
- }
- ]
- }
- return (
- <div>
- <div>
- <ProTable
- bordered
- rowKey={record => record.day15 + Date.now()}
- columns={columns}
- dataSource={state.reminderData}
- search={false}
- toolBarRender={false}
- pagination={false}
- />
- </div>
- <div className="mt-4">
- <div className="p-4 bg-white border rounded-lg shadow-card">
- <Row gutter={16}>
- <Col className="gutter-row" span={6}>
- <div className="p-4 bg-white border rounded-lg">
- <Row>
- <Col span={6}>
- <div className="w-48px h-48px border rounded-48px bg-[#0c7cd5] relative">
- <span className="absolute top-9px left-9px">
- <City size="26" fill="#fff" />
- </span>
- </div>
- </Col>
- <Col span={9}>
- <h3 className="text-2xl">{state.customerChainRatio.count}</h3>
- <span>新增客户</span>
- </Col>
- <Col span={9} className="text-right">
- <h3 className="text-xl text-green-500">
- {state.customerChainRatio.percentage}
- </h3>
- <span>较上月</span>
- </Col>
- </Row>
- </div>
- </Col>
- <Col className="gutter-row" span={6}>
- <div className="p-4 bg-white border rounded-lg shadow-card">
- <Row>
- <Col span={6}>
- <div className="w-48px h-48px border rounded-48px bg-[#0c7cd5] relative">
- <span className="absolute top-10px left-10px">
- <AddressBook size="26" fill="#fff" />
- </span>
- </div>
- </Col>
- <Col span={9}>
- <h3 className="text-2xl">{state.clientChainRatio.count}</h3>
- <span>新增联系人</span>
- </Col>
- <Col span={9} className="text-right">
- <h3 className="text-xl text-red-500">{state.clientChainRatio.percentage}</h3>
- <span>较上月</span>
- </Col>
- </Row>
- </div>
- </Col>
- <Col className="gutter-row" span={6}>
- <div className="p-4 bg-white border rounded-lg">
- <Row>
- <Col span={6}>
- <div className="w-48px h-48px border rounded-48px bg-[#0c7cd5] relative">
- <span className="absolute top-10px left-10px">
- <Finance size="26" fill="#fff" />
- </span>
- </div>
- </Col>
- <Col span={9}>
- <h3 className="text-2xl">{state.businessChainRatio.count}</h3>
- <span>新增商机</span>
- </Col>
- <Col span={9} className="text-right">
- <h3 className="text-xl text-green-500">
- {state.businessChainRatio.percentage}
- </h3>
- <span>较上月</span>
- </Col>
- </Row>
- </div>
- </Col>
- <Col className="gutter-row" span={6}>
- <div className="p-4 bg-white border rounded-lg">
- <Row>
- <Col span={6}>
- <div className="w-48px h-48px border rounded-48px bg-[#0c7cd5] relative">
- <span className="absolute top-10px left-10px">
- <Comment size="26" fill="#fff" />
- </span>
- </div>
- </Col>
- <Col span={9}>
- <h3 className="text-2xl">{state.serviceLogChainRatio.count}</h3>
- <span>服务记录</span>
- </Col>
- <Col span={9} className="text-right">
- <h3 className="text-xl text-green-500">
- {state.serviceLogChainRatio.percentage}
- </h3>
- <span>较上月</span>
- </Col>
- </Row>
- </div>
- </Col>
- </Row>
- </div>
- </div>
- <div className="mt-4">
- <Row gutter={16}>
- <Col className="gutter-row" span={16}>
- <div className="p-4 bg-white border rounded-lg shadow-card">
- <div className="relative">
- <span>销售漏斗</span>
- <div className="absolute right-1 top-0">
- <Select defaultValue="销售漏斗组">
- <Option value="销售漏斗组">销售漏斗组</Option>
- </Select>
- </div>
- </div>
- <Divider />
- <DualAxes {...config} />
- </div>
- </Col>
- <Col className="gutter-row" span={8}>
- <div className="bg-white border rounded-lg shadow-card">
- <h4 className="px-12px py-16px border-b-1">数据汇总</h4>
- <ul>
- <li className="px-12px py-16px border-b-1">
- 新增客户<b className="px-1">{state.aggregation.customerCount}</b>个,服务
- <b className="px-1">{state.aggregation.customerServiceCount}</b>条
- </li>
- <li className="px-12px py-16px border-b-1">
- 新增联系人<b className="px-1">{state.aggregation.clientCount}</b>个,服务
- <b className="px-1">{state.aggregation.clientServiceCount}</b> 条
- </li>
- <li className="px-12px py-16px">
- 新增商机<b className="px-1">{state.aggregation.businessCount}</b>个,金额
- <b className="px-1">{state.aggregation.businessSum}</b> 元,服务
- <b className="px-1">{state.aggregation.businessServiceCount}</b>
- 条,赢单<b className="px-1">{state.aggregation.businessWinCount}</b>个
- </li>
- </ul>
- </div>
- </Col>
- </Row>
- </div>
- <div className="mt-4">
- <Row gutter={16}>
- <Col className="gutter-row" span={12}>
- <div className="bg-white border rounded-lg shadow-card">
- <LeaderBoard dataList={state.leaderboard} />
- </div>
- </Col>
- </Row>
- </div>
- </div>
- )
- }
- export default Dashboard
|