RatioPanels.tsx 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. import React, { useState } from 'react'
  2. import ProTable from '@ant-design/pro-table'
  3. import { queryRatioPanelsList, queryServiceRatioPanelsList } from '@/services/dashboard'
  4. import consts from '@/consts'
  5. import { CardTypeMap } from '../util'
  6. import { Badge, Modal } from 'antd'
  7. import { useModal } from '@/components/ModalStore'
  8. import { servicelogEnum } from '@/pages/Customer/Client/components/ClientDetail/LowerList'
  9. const dataTypeMap = {
  10. [CardTypeMap.CLIENT]: {
  11. key: 'client',
  12. title: '新增客户'
  13. },
  14. [CardTypeMap.COMPANY]: {
  15. key: 'customer',
  16. title: '新增单位'
  17. },
  18. [CardTypeMap.BUSINESS]: {
  19. key: 'business',
  20. title: '新增商机'
  21. },
  22. [CardTypeMap.SERVICE]: {
  23. key: 'service',
  24. title: '新增服务记录'
  25. }
  26. }
  27. export const renderBadge = (count, active = false) => {
  28. return active ? (
  29. <Badge
  30. count={count}
  31. style={{
  32. marginTop: -2,
  33. marginLeft: 4,
  34. color: '#531dab',
  35. backgroundColor: '#f9f0ff'
  36. }}
  37. />
  38. ) : null
  39. }
  40. /** 服务环比数据Tab切换表格 */
  41. const ServiceRatioPanels = ({ dispatchModal, staffIds, cyclical, dataPermission }) => {
  42. const activeKeyMap = {
  43. 0: { key: 'clientName', title: '客户', id: 'clientId' },
  44. 1: { key: 'customerName', title: '单位', id: 'customerId' },
  45. 2: { key: 'businessName', title: '商机', id: 'businessId' }
  46. }
  47. const [state, setState] = useState({
  48. activeKey: '0',
  49. total: 0
  50. })
  51. const showDrawer = id => {
  52. if (state.activeKey === '0') {
  53. dispatchModal('D_CLIENT_DETAIL', { dataId: id })
  54. }
  55. if (state.activeKey === '1') {
  56. dispatchModal('D_COMPANY_DETAIL', { dataId: id })
  57. }
  58. }
  59. const columns = [
  60. {
  61. dataIndex: activeKeyMap[state.activeKey].key,
  62. title: `${activeKeyMap[state.activeKey].title}名称`,
  63. width: '15%',
  64. render: (text, record) => (
  65. <span
  66. onClick={() => showDrawer(record[activeKeyMap[state.activeKey].id])}
  67. className="text-primary cursor-pointer hover:text-hex-967bbd">
  68. {text}
  69. </span>
  70. )
  71. },
  72. {
  73. dataIndex: 'status',
  74. title: '服务类型',
  75. width: '8%',
  76. render: type => servicelogEnum[type]?.title
  77. },
  78. {
  79. dataIndex: 'date',
  80. title: '服务日期',
  81. width: '9%',
  82. valueType: 'date'
  83. },
  84. {
  85. dataIndex: 'mark',
  86. width: '38%',
  87. ellipsis: true,
  88. title: '服务内容'
  89. },
  90. {
  91. dataIndex: 'staffName',
  92. title: '创建人',
  93. width: '7%'
  94. }
  95. ]
  96. return (
  97. <ProTable
  98. size="small"
  99. params={{ dataType: state.activeKey, cyclical, dataPermission, staffIds }}
  100. rowKey={record => record.id}
  101. scroll={{ y: 400 }}
  102. bordered={true}
  103. cardProps={{ bodyStyle: { padding: 0 } }}
  104. columns={columns}
  105. search={false}
  106. toolbar={{
  107. settings: false,
  108. menu: {
  109. type: 'tab',
  110. activeKey: state.activeKey,
  111. items: [
  112. {
  113. key: '0',
  114. label: (
  115. <span>
  116. 客户
  117. {renderBadge(state.total, state.activeKey === '0')}
  118. </span>
  119. )
  120. },
  121. {
  122. key: '1',
  123. label: (
  124. <span>
  125. 单位
  126. {renderBadge(state.total, state.activeKey === '1')}
  127. </span>
  128. )
  129. },
  130. {
  131. key: '2',
  132. label: (
  133. <span>
  134. 商机
  135. {renderBadge(state.total, state.activeKey === '2')}
  136. </span>
  137. )
  138. }
  139. ],
  140. onChange: key => {
  141. setState({ ...state, activeKey: key })
  142. // redoHeight()
  143. }
  144. }
  145. }}
  146. pagination={{ defaultPageSize: 10, showQuickJumper: true }}
  147. request={async params => {
  148. const { code = -1, data } = await queryServiceRatioPanelsList(params)
  149. setState({ ...state, total: data.total || 0 })
  150. return {
  151. data: data.log,
  152. success: code === consts.RET_CODE.SUCCESS,
  153. total: data.total
  154. }
  155. }}
  156. />
  157. )
  158. }
  159. const RatioPanels = ({ dataType, staffIds, retioCyclical, dataPermission, ...resetModalProps }) => {
  160. const dispatchModal = useModal()
  161. const columnsMap = {
  162. 0: [
  163. {
  164. dataIndex: 'clientName',
  165. title: '客户名称',
  166. width: '10%',
  167. render: (clientName, record) => (
  168. <span
  169. onClick={() => dispatchModal('D_CLIENT_DETAIL', { dataId: record.id })}
  170. className="text-primary cursor-pointer hover:text-[#967bbd]">
  171. {clientName}
  172. </span>
  173. )
  174. },
  175. {
  176. dataIndex: 'companyName',
  177. title: '单位名称',
  178. width: '16%',
  179. ellipsis: true,
  180. render: (companyName, record) => (
  181. <span
  182. className="text-primary cursor-pointer hover:text-[#967bbd]"
  183. onClick={() => dispatchModal('D_COMPANY_DETAIL', { dataId: record.companyId })}>
  184. {companyName}
  185. </span>
  186. )
  187. },
  188. {
  189. dataIndex: 'districtName',
  190. title: '地区',
  191. width: '15%',
  192. ellipsis: true,
  193. renderText: text => text && text?.replaceAll(' / ', ' , ')
  194. },
  195. {
  196. dataIndex: 'phone',
  197. title: '手机',
  198. ellipsis: true,
  199. width: '5%'
  200. },
  201. {
  202. dataIndex: 'email',
  203. title: '邮箱',
  204. ellipsis: true,
  205. width: '7%'
  206. },
  207. {
  208. dataIndex: 'qq',
  209. title: 'QQ',
  210. ellipsis: true,
  211. width: '5%'
  212. },
  213. {
  214. dataIndex: 'staffName',
  215. title: '创建人',
  216. ellipsis: true,
  217. width: '7%'
  218. },
  219. {
  220. dataIndex: 'createTime',
  221. title: '创建时间',
  222. ellipsis: true,
  223. width: '7%'
  224. }
  225. ],
  226. 1: [
  227. {
  228. dataIndex: 'companyName',
  229. title: '单位名称',
  230. width: '16%',
  231. render: (companyName, record) => (
  232. <span
  233. onClick={() => dispatchModal('D_COMPANY_DETAIL', { dataId: record.id })}
  234. className="text-primary cursor-pointer hover:text-[#967bbd]">
  235. {companyName}
  236. </span>
  237. )
  238. },
  239. {
  240. dataIndex: 'districtName',
  241. title: '地区',
  242. width: '15%',
  243. ellipsis: true,
  244. renderText: text => text && text?.replaceAll(' / ', ' , ')
  245. },
  246. {
  247. dataIndex: 'nature',
  248. title: '单位性质',
  249. ellipsis: true,
  250. width: '14%'
  251. },
  252. {
  253. dataIndex: 'phone',
  254. title: '单位电话',
  255. ellipsis: true,
  256. width: '5%'
  257. },
  258. {
  259. dataIndex: 'staffName',
  260. title: '创建人',
  261. ellipsis: true,
  262. width: '7%'
  263. },
  264. {
  265. dataIndex: 'createTime',
  266. title: '创建时间',
  267. ellipsis: true,
  268. width: '7%'
  269. }
  270. ],
  271. 2: [
  272. {
  273. dataIndex: 'name',
  274. title: '商机名称',
  275. width: '15%'
  276. },
  277. {
  278. dataIndex: 'customerName',
  279. title: '单位名称',
  280. ellipsis: true,
  281. width: '20%'
  282. },
  283. {
  284. dataIndex: 'businessStatusName',
  285. title: '商机状态',
  286. ellipsis: true,
  287. width: '5%'
  288. },
  289. {
  290. dataIndex: 'price',
  291. title: '商机金额',
  292. ellipsis: true,
  293. width: '5%'
  294. },
  295. {
  296. dataIndex: 'staffName',
  297. title: '创建人',
  298. ellipsis: true,
  299. width: '7%'
  300. },
  301. {
  302. dataIndex: 'createTime',
  303. title: '创建时间',
  304. ellipsis: true,
  305. width: '7%'
  306. }
  307. ]
  308. }
  309. return (
  310. <Modal
  311. {...resetModalProps}
  312. title={`卡片详情(${dataTypeMap[dataType].title})`}
  313. footer={false}
  314. getContainer={() => document.getElementById('root')}
  315. width="90vw">
  316. {dataType === CardTypeMap.SERVICE ? (
  317. <ServiceRatioPanels
  318. dispatchModal={dispatchModal}
  319. cyclical={retioCyclical}
  320. dataPermission={dataPermission}
  321. staffIds={staffIds}
  322. />
  323. ) : (
  324. <div className="mx-4">
  325. <ProTable
  326. size="small"
  327. bordered={true}
  328. cardProps={{ bodyStyle: { padding: 0 } }}
  329. pagination={{ defaultPageSize: 10 }}
  330. rowKey={record => record.id}
  331. scroll={{ y: 400 }}
  332. columns={columnsMap[dataType]}
  333. params={{ dataType, dataPermission, cyclical: retioCyclical, staffIds }}
  334. request={async params => {
  335. const { code = -1, data } = await queryRatioPanelsList(params)
  336. return {
  337. data: data[dataTypeMap[dataType].key],
  338. success: code === consts.RET_CODE.SUCCESS,
  339. total: data.total
  340. }
  341. }}
  342. search={false}
  343. toolBarRender={false}
  344. />
  345. </div>
  346. )}
  347. </Modal>
  348. )
  349. }
  350. export default RatioPanels