|
|
@@ -18,6 +18,7 @@ import { isDevMode } from '@/utils/env'
|
|
|
import { isMobile } from '@/utils/is'
|
|
|
import { useModal } from '@/components/ModalStore'
|
|
|
import classNames from 'classnames'
|
|
|
+import { PageContainer } from '@ant-design/pro-layout'
|
|
|
|
|
|
const Dashboard = ({ dispatch, departments = [] }) => {
|
|
|
const { initialState: { currentUser } = { currentUser: {} } } = useModel('@@initialState')
|
|
|
@@ -292,181 +293,184 @@ const Dashboard = ({ dispatch, departments = [] }) => {
|
|
|
setState({ ...state, immediate: true, params: { ...state.params, cyclical: value } })
|
|
|
}
|
|
|
return (
|
|
|
- <div className={styles.dashboard}>
|
|
|
- <div>
|
|
|
- <Row gutter={[8, 8]}>
|
|
|
- <Col xs={24} sm={24} md={24} lg={18} xl={18}>
|
|
|
- <div className="shadow-card">
|
|
|
- <ProTable
|
|
|
- bordered
|
|
|
+ <PageContainer title={false} breadcrumb={false} waterMarkProps={{ offsetTop: 111 }}>
|
|
|
+ <div className={styles.dashboard}>
|
|
|
+ <div>
|
|
|
+ <Row gutter={[8, 8]}>
|
|
|
+ <Col xs={24} sm={24} md={24} lg={18} xl={18}>
|
|
|
+ <div className="shadow-card">
|
|
|
+ <ProTable
|
|
|
+ bordered
|
|
|
+ loading={state.loading}
|
|
|
+ rowKey={record => record.type + Date.now()}
|
|
|
+ columns={columns}
|
|
|
+ dataSource={state.reminderData}
|
|
|
+ search={false}
|
|
|
+ toolBarRender={false}
|
|
|
+ tableRender={(_, dom) => (
|
|
|
+ <Card bodyStyle={{ padding: state.loading ? '24px' : 0 }} loading={state.loading}>
|
|
|
+ {dom}
|
|
|
+ </Card>
|
|
|
+ )}
|
|
|
+ pagination={false}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </Col>
|
|
|
+ <Col xs={24} sm={24} md={24} lg={6} xl={6}>
|
|
|
+ <div className="shadow-card">
|
|
|
+ <ProTable
|
|
|
+ bordered
|
|
|
+ loading={state.loading}
|
|
|
+ rowKey={record => record.type + Date.now()}
|
|
|
+ columns={columnsSmall}
|
|
|
+ dataSource={state.reminderData}
|
|
|
+ search={false}
|
|
|
+ toolBarRender={false}
|
|
|
+ tableRender={(_, dom) => (
|
|
|
+ <Card bodyStyle={{ padding: state.loading ? '24px' : 0 }} loading={state.loading}>
|
|
|
+ {dom}
|
|
|
+ </Card>
|
|
|
+ )}
|
|
|
+ pagination={false}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="flex flex-wrap">
|
|
|
+ <div className="mr-4 my-4 flex">
|
|
|
+ <Select
|
|
|
+ disabled={state.disabled}
|
|
|
+ loading={state.loading}
|
|
|
+ options={cyclicalOp}
|
|
|
+ dropdownMatchSelectWidth={false}
|
|
|
+ defaultValue={defaultCyclicalValue}
|
|
|
+ onChange={handleCyclicalChange}
|
|
|
+ />
|
|
|
+ <div className="mx-2">
|
|
|
+ <PermSelect
|
|
|
loading={state.loading}
|
|
|
- rowKey={record => record.type + Date.now()}
|
|
|
- columns={columns}
|
|
|
- dataSource={state.reminderData}
|
|
|
- search={false}
|
|
|
- toolBarRender={false}
|
|
|
- tableRender={(_, dom) => (
|
|
|
- <Card bodyStyle={{ padding: state.loading ? '24px' : 0 }} loading={state.loading}>
|
|
|
- {dom}
|
|
|
- </Card>
|
|
|
- )}
|
|
|
- pagination={false}
|
|
|
+ disabled={state.disabled}
|
|
|
+ onConfirm={handlePermChange}
|
|
|
+ dataType="workbench"
|
|
|
/>
|
|
|
</div>
|
|
|
- </Col>
|
|
|
- <Col xs={24} sm={24} md={24} lg={6} xl={6}>
|
|
|
- <div className="shadow-card">
|
|
|
- <ProTable
|
|
|
- bordered
|
|
|
+ {state.params.dataPermission === 'all' ? (
|
|
|
+ <TreeSelect
|
|
|
+ size="middle"
|
|
|
+ style={{ width: 150 }}
|
|
|
+ dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
|
|
loading={state.loading}
|
|
|
- rowKey={record => record.type + Date.now()}
|
|
|
- columns={columnsSmall}
|
|
|
- dataSource={state.reminderData}
|
|
|
- search={false}
|
|
|
- toolBarRender={false}
|
|
|
- tableRender={(_, dom) => (
|
|
|
- <Card bodyStyle={{ padding: state.loading ? '24px' : 0 }} loading={state.loading}>
|
|
|
- {dom}
|
|
|
- </Card>
|
|
|
- )}
|
|
|
- pagination={false}
|
|
|
+ disabled={state.disabled}
|
|
|
+ treeDefaultExpandAll
|
|
|
+ placeholder="办事处"
|
|
|
+ treeData={departments}
|
|
|
+ allowClear
|
|
|
+ onSelect={queryStaffList}
|
|
|
+ onChange={e => {
|
|
|
+ if (!e)
|
|
|
+ setState({
|
|
|
+ ...state,
|
|
|
+ params: { ...state.params, staffIds: null },
|
|
|
+ staffList: [],
|
|
|
+ selectId: null
|
|
|
+ })
|
|
|
+ }}
|
|
|
/>
|
|
|
- </div>
|
|
|
- </Col>
|
|
|
- </Row>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div className="flex flex-wrap">
|
|
|
- <div className="mr-4 my-4 flex">
|
|
|
- <Select
|
|
|
- disabled={state.disabled}
|
|
|
- loading={state.loading}
|
|
|
- options={cyclicalOp}
|
|
|
- dropdownMatchSelectWidth={false}
|
|
|
- defaultValue={defaultCyclicalValue}
|
|
|
- onChange={handleCyclicalChange}
|
|
|
- />
|
|
|
- <div className="mx-2">
|
|
|
- <PermSelect
|
|
|
- loading={state.loading}
|
|
|
- disabled={state.disabled}
|
|
|
- onConfirm={handlePermChange}
|
|
|
- dataType="workbench"
|
|
|
- />
|
|
|
+ ) : null}
|
|
|
</div>
|
|
|
- {state.params.dataPermission === 'all' ? (
|
|
|
- <TreeSelect
|
|
|
- size="middle"
|
|
|
- style={{ width: 150 }}
|
|
|
- dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
|
|
- loading={state.loading}
|
|
|
- disabled={state.disabled}
|
|
|
- treeDefaultExpandAll
|
|
|
- placeholder="办事处"
|
|
|
- treeData={departments}
|
|
|
- allowClear
|
|
|
- onSelect={queryStaffList}
|
|
|
- onChange={e => {
|
|
|
- if (!e)
|
|
|
- setState({
|
|
|
- ...state,
|
|
|
- params: { ...state.params, staffIds: null },
|
|
|
- staffList: [],
|
|
|
- selectId: null
|
|
|
- })
|
|
|
- }}
|
|
|
- />
|
|
|
- ) : null}
|
|
|
- </div>
|
|
|
|
|
|
- <div className="flex items-center flex-row ml-2">
|
|
|
- {['all', 'department'].includes(state.params.dataPermission) &&
|
|
|
- state.staffList.map(item => (
|
|
|
- <div
|
|
|
- className={classNames('relative cursor-pointer', styles.staffItem, {
|
|
|
- [styles.active]: state.selectId === item.id
|
|
|
- })}
|
|
|
- key={item.id}
|
|
|
- onClick={() => handleStaffClick(item.id)}>
|
|
|
- <img
|
|
|
- className="w-full max-w-30px h-30px border rounded-30px"
|
|
|
- src={
|
|
|
- (isDevMode() ? 'http://cld2qa.com' : 'http://zhcld.com') +
|
|
|
- (item?.avatar ?? consts.DEFAULT_AVATAR)
|
|
|
- }
|
|
|
- />
|
|
|
- <span className={styles.extra}>{item.username}</span>
|
|
|
- </div>
|
|
|
- ))}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <Row gutter={[8, 8]}>
|
|
|
- <Col xs={24} sm={24} md={24} lg={8} xl={8}>
|
|
|
- <div className="p-4 bg-white border rounded-2px border-hex-f0f0f0 shadow-card">
|
|
|
- {state.loading ? (
|
|
|
- <Skeleton active avatar />
|
|
|
- ) : (
|
|
|
- <Row className="cursor-pointer" onClick={() => handleRatioCard(cardTypeMap.CLIENT)}>
|
|
|
- <Col span={6}>
|
|
|
- <div className="w-full max-w-48px h-48px border rounded-48px bg-[#0c7cd5] flex items-center justify-center">
|
|
|
- <AddressBook size="26" fill="#fff" />
|
|
|
- </div>
|
|
|
- </Col>
|
|
|
- <Col span={18} flex="wrap">
|
|
|
- <div className="flex items-center justify-between ">
|
|
|
- <div className="text-2xl">{state.clientChainRatio.count}</div>
|
|
|
- <span
|
|
|
- className={[
|
|
|
- 'text-xl',
|
|
|
- state.clientChainRatio.percentage.startsWith('-') ? 'text-green-500' : 'text-red-500'
|
|
|
- ].join(' ')}>
|
|
|
- {state.clientChainRatio.percentage}
|
|
|
- </span>
|
|
|
- </div>
|
|
|
- <div className="flex justify-between items-center">
|
|
|
- <div>新增客户</div>
|
|
|
- <span>{cyclicalOp.find(item => item.value === state.params.cyclical)?.title}</span>
|
|
|
- </div>
|
|
|
- </Col>
|
|
|
- </Row>
|
|
|
- )}
|
|
|
+ <div className="flex items-center flex-row ml-2">
|
|
|
+ {['all', 'department'].includes(state.params.dataPermission) &&
|
|
|
+ state.staffList.map(item => (
|
|
|
+ <div
|
|
|
+ className={classNames('relative cursor-pointer', styles.staffItem, {
|
|
|
+ [styles.active]: state.selectId === item.id
|
|
|
+ })}
|
|
|
+ key={item.id}
|
|
|
+ onClick={() => handleStaffClick(item.id)}>
|
|
|
+ <img
|
|
|
+ className="w-full max-w-30px h-30px border rounded-30px"
|
|
|
+ src={
|
|
|
+ (isDevMode() ? 'http://cld2qa.com' : 'http://zhcld.com') +
|
|
|
+ (item?.avatar ?? consts.DEFAULT_AVATAR)
|
|
|
+ }
|
|
|
+ />
|
|
|
+ <span className={styles.extra}>{item.username}</span>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
</div>
|
|
|
- </Col>
|
|
|
- <Col xs={24} sm={24} md={24} lg={8} xl={8}>
|
|
|
- <div className="p-4 bg-white border rounded-2px border-hex-f0f0f0 shadow-card">
|
|
|
- {state.loading ? (
|
|
|
- <Skeleton active avatar />
|
|
|
- ) : (
|
|
|
- <Row className="cursor-pointer" onClick={() => handleRatioCard(cardTypeMap.COMPANY)}>
|
|
|
- <Col span={6}>
|
|
|
- <div className="w-full max-w-48px h-48px border rounded-48px bg-[#0c7cd5] flex items-center justify-center">
|
|
|
- <City size="26" fill="#fff" />
|
|
|
- </div>
|
|
|
- </Col>
|
|
|
- <Col span={18} flex="wrap">
|
|
|
- <div className="flex items-center justify-between ">
|
|
|
- <div className="text-2xl">{state.customerChainRatio.count}</div>
|
|
|
- <span
|
|
|
- className={[
|
|
|
- 'text-xl',
|
|
|
- state.customerChainRatio.percentage.startsWith('-')
|
|
|
- ? 'text-green-500'
|
|
|
- : 'text-red-500'
|
|
|
- ].join(' ')}>
|
|
|
- {state.customerChainRatio.percentage}
|
|
|
- </span>
|
|
|
- </div>
|
|
|
+ </div>
|
|
|
+ <Row gutter={[8, 8]}>
|
|
|
+ <Col xs={24} sm={24} md={24} lg={8} xl={8}>
|
|
|
+ <div className="p-4 bg-white border rounded-2px border-hex-f0f0f0 shadow-card">
|
|
|
+ {state.loading ? (
|
|
|
+ <Skeleton active avatar />
|
|
|
+ ) : (
|
|
|
+ <Row className="cursor-pointer" onClick={() => handleRatioCard(cardTypeMap.CLIENT)}>
|
|
|
+ <Col span={6}>
|
|
|
+ <div className="w-full max-w-48px h-48px border rounded-48px bg-[#0c7cd5] flex items-center justify-center">
|
|
|
+ <AddressBook size="26" fill="#fff" />
|
|
|
+ </div>
|
|
|
+ </Col>
|
|
|
+ <Col span={18} flex="wrap">
|
|
|
+ <div className="flex items-center justify-between ">
|
|
|
+ <div className="text-2xl">{state.clientChainRatio.count}</div>
|
|
|
+ <span
|
|
|
+ className={[
|
|
|
+ 'text-xl',
|
|
|
+ state.clientChainRatio.percentage.startsWith('-')
|
|
|
+ ? 'text-green-500'
|
|
|
+ : 'text-red-500'
|
|
|
+ ].join(' ')}>
|
|
|
+ {state.clientChainRatio.percentage}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div className="flex justify-between items-center">
|
|
|
+ <div>新增客户</div>
|
|
|
+ <span>{cyclicalOp.find(item => item.value === state.params.cyclical)?.title}</span>
|
|
|
+ </div>
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </Col>
|
|
|
+ <Col xs={24} sm={24} md={24} lg={8} xl={8}>
|
|
|
+ <div className="p-4 bg-white border rounded-2px border-hex-f0f0f0 shadow-card">
|
|
|
+ {state.loading ? (
|
|
|
+ <Skeleton active avatar />
|
|
|
+ ) : (
|
|
|
+ <Row className="cursor-pointer" onClick={() => handleRatioCard(cardTypeMap.COMPANY)}>
|
|
|
+ <Col span={6}>
|
|
|
+ <div className="w-full max-w-48px h-48px border rounded-48px bg-[#0c7cd5] flex items-center justify-center">
|
|
|
+ <City size="26" fill="#fff" />
|
|
|
+ </div>
|
|
|
+ </Col>
|
|
|
+ <Col span={18} flex="wrap">
|
|
|
+ <div className="flex items-center justify-between ">
|
|
|
+ <div className="text-2xl">{state.customerChainRatio.count}</div>
|
|
|
+ <span
|
|
|
+ className={[
|
|
|
+ 'text-xl',
|
|
|
+ state.customerChainRatio.percentage.startsWith('-')
|
|
|
+ ? 'text-green-500'
|
|
|
+ : 'text-red-500'
|
|
|
+ ].join(' ')}>
|
|
|
+ {state.customerChainRatio.percentage}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
|
|
|
- <div className="flex justify-between items-center">
|
|
|
- <div>新增单位</div>
|
|
|
- <span>{cyclicalOp.find(item => item.value === state.params.cyclical)?.title}</span>
|
|
|
- </div>
|
|
|
- </Col>
|
|
|
- </Row>
|
|
|
- )}
|
|
|
- </div>
|
|
|
- </Col>
|
|
|
- {/* <Col xs={24} sm={24} md={24} lg={6} xl={6}>
|
|
|
+ <div className="flex justify-between items-center">
|
|
|
+ <div>新增单位</div>
|
|
|
+ <span>{cyclicalOp.find(item => item.value === state.params.cyclical)?.title}</span>
|
|
|
+ </div>
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </Col>
|
|
|
+ {/* <Col xs={24} sm={24} md={24} lg={6} xl={6}>
|
|
|
<div className="p-4 bg-white border rounded-2px border-hex-f0f0f0 shadow-card">
|
|
|
{state.loading ? (
|
|
|
<Skeleton active avatar />
|
|
|
@@ -504,44 +508,44 @@ const Dashboard = ({ dispatch, departments = [] }) => {
|
|
|
)}
|
|
|
</div>
|
|
|
</Col> */}
|
|
|
- <Col xs={24} sm={24} md={24} lg={8} xl={8}>
|
|
|
- <div className="p-4 bg-white border rounded-2px border-hex-f0f0f0 shadow-card">
|
|
|
- {state.loading ? (
|
|
|
- <Skeleton active avatar />
|
|
|
- ) : (
|
|
|
- <Row onClick={() => handleRatioCard(cardTypeMap.SERVICE)} className="cursor-pointer">
|
|
|
- <Col span={6}>
|
|
|
- <div className="w-full max-w-48px h-48px border rounded-48px bg-[#0c7cd5] flex items-center justify-center">
|
|
|
- <Comment size="26" fill="#fff" />
|
|
|
- </div>
|
|
|
- </Col>
|
|
|
- <Col span={18} flex="wrap">
|
|
|
- <div className="flex items-center justify-between ">
|
|
|
- <div className="text-2xl">{state.serviceLogChainRatio.count}</div>
|
|
|
- <span
|
|
|
- className={[
|
|
|
- 'text-xl',
|
|
|
- state.serviceLogChainRatio.percentage.startsWith('-')
|
|
|
- ? 'text-green-500'
|
|
|
- : 'text-red-500'
|
|
|
- ].join(' ')}>
|
|
|
- {state.serviceLogChainRatio.percentage}
|
|
|
- </span>
|
|
|
- </div>
|
|
|
+ <Col xs={24} sm={24} md={24} lg={8} xl={8}>
|
|
|
+ <div className="p-4 bg-white border rounded-2px border-hex-f0f0f0 shadow-card">
|
|
|
+ {state.loading ? (
|
|
|
+ <Skeleton active avatar />
|
|
|
+ ) : (
|
|
|
+ <Row onClick={() => handleRatioCard(cardTypeMap.SERVICE)} className="cursor-pointer">
|
|
|
+ <Col span={6}>
|
|
|
+ <div className="w-full max-w-48px h-48px border rounded-48px bg-[#0c7cd5] flex items-center justify-center">
|
|
|
+ <Comment size="26" fill="#fff" />
|
|
|
+ </div>
|
|
|
+ </Col>
|
|
|
+ <Col span={18} flex="wrap">
|
|
|
+ <div className="flex items-center justify-between ">
|
|
|
+ <div className="text-2xl">{state.serviceLogChainRatio.count}</div>
|
|
|
+ <span
|
|
|
+ className={[
|
|
|
+ 'text-xl',
|
|
|
+ state.serviceLogChainRatio.percentage.startsWith('-')
|
|
|
+ ? 'text-green-500'
|
|
|
+ : 'text-red-500'
|
|
|
+ ].join(' ')}>
|
|
|
+ {state.serviceLogChainRatio.percentage}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
|
|
|
- <div className="flex justify-between items-center">
|
|
|
- <div>服务记录</div>
|
|
|
- <span>{cyclicalOp.find(item => item.value === state.params.cyclical)?.title}</span>
|
|
|
- </div>
|
|
|
- </Col>
|
|
|
- </Row>
|
|
|
- )}
|
|
|
- </div>
|
|
|
- </Col>
|
|
|
- </Row>
|
|
|
- <div className="mt-4">
|
|
|
- <Row gutter={[8, 8]}>
|
|
|
- {/* <Col xs={24} sm={24} md={24} lg={12} xl={12}>
|
|
|
+ <div className="flex justify-between items-center">
|
|
|
+ <div>服务记录</div>
|
|
|
+ <span>{cyclicalOp.find(item => item.value === state.params.cyclical)?.title}</span>
|
|
|
+ </div>
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ <div className="mt-4">
|
|
|
+ <Row gutter={[8, 8]}>
|
|
|
+ {/* <Col xs={24} sm={24} md={24} lg={12} xl={12}>
|
|
|
<BusinessChar
|
|
|
loading={state.loading}
|
|
|
data={state.businessChar}
|
|
|
@@ -549,44 +553,45 @@ const Dashboard = ({ dispatch, departments = [] }) => {
|
|
|
/>
|
|
|
</Col> */}
|
|
|
|
|
|
- <Col xs={24} sm={24} md={24} lg={24} xl={24}>
|
|
|
- <Card
|
|
|
- headStyle={{ padding: '0 12px' }}
|
|
|
- title="数据汇总"
|
|
|
- className="shadow-card"
|
|
|
- bodyStyle={{ padding: state.loading ? '24px' : 0 }}
|
|
|
- loading={state.loading}>
|
|
|
- <ul>
|
|
|
- <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 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">
|
|
|
- 新增商机<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>
|
|
|
- </Card>
|
|
|
- </Col>
|
|
|
- </Row>
|
|
|
- </div>
|
|
|
- <div className="mt-4">
|
|
|
- <Row gutter={[8, 8]}>
|
|
|
- <Col xs={24} sm={24} md={24} lg={12} xl={12}>
|
|
|
- <LeaderBoard dataList={state.leaderboard} loading={state.loading} />
|
|
|
- </Col>
|
|
|
- <Col xs={24} sm={24} md={24} lg={12} xl={12}>
|
|
|
- <SoftLeaderboard productLeaderBoard={state.productLeaderBoard} loading={state.loading} />
|
|
|
- </Col>
|
|
|
- </Row>
|
|
|
+ <Col xs={24} sm={24} md={24} lg={24} xl={24}>
|
|
|
+ <Card
|
|
|
+ headStyle={{ padding: '0 12px' }}
|
|
|
+ title="数据汇总"
|
|
|
+ className="shadow-card"
|
|
|
+ bodyStyle={{ padding: state.loading ? '24px' : 0 }}
|
|
|
+ loading={state.loading}>
|
|
|
+ <ul>
|
|
|
+ <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 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">
|
|
|
+ 新增商机<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>
|
|
|
+ </Card>
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ </div>
|
|
|
+ <div className="mt-4">
|
|
|
+ <Row gutter={[8, 8]}>
|
|
|
+ <Col xs={24} sm={24} md={24} lg={12} xl={12}>
|
|
|
+ <LeaderBoard dataList={state.leaderboard} loading={state.loading} />
|
|
|
+ </Col>
|
|
|
+ <Col xs={24} sm={24} md={24} lg={12} xl={12}>
|
|
|
+ <SoftLeaderboard productLeaderBoard={state.productLeaderBoard} loading={state.loading} />
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
+ </PageContainer>
|
|
|
)
|
|
|
}
|
|
|
|